3254. Find the Power of K-Size Subarrays I
Problem Description
You are given an array of integers nums
of length n
and a positive integer k
.
The power of an array is defined as:
- Its maximum element if all of its elements are consecutive and sorted in ascending order.
-1
otherwise.
You need to find the power of all subarrays of nums
of size k
.
Return an integer array results
of size n - k + 1
, where results[i]
is the power of nums[i..(i + k - 1)]
.
Intuition
To solve the problem, we first need to determine if each subarray of size k
within nums
consists of consecutive elements in ascending order. The solution makes use of an auxiliary array f
which helps in tracking the length of the current consecutive increasing elements.
-
Auxiliary Array Initialization: We initialize an array
f
of the same length asnums
, where each element is set to1
. This array helps in storing the length of consecutive increasing integers ending at each position innums
. -
Building Consecutive Lengths: While iterating through
nums
, if the current element is exactly1
more than the previous one (nums[i] == nums[i - 1] + 1
), it means the streak of consecutive numbers continues, and we increment the consecutive length count (f[i] = f[i - 1] + 1
). Otherwise, the streak is broken, so we resetf[i]
to1
. -
Determine Subarray Power: For each subarray defined by its end index
i
(starting fromk - 1
ton
), we check if it forms a sequence of at leastk
consecutive numbers by verifying iff[i]
is greater than or equal tok
. If true, the power is the maximum number of this ascending sequence, which isnums[i]
. If not, we assign-1
to denote the subarray doesn’t satisfy the condition. -
Return Results: Ultimately, we construct an array capturing the power of each k-sized subarray and return it.
The approach efficiently tracks the consecutive sequences and utilizes the established conditions to determine the power with minimum computations.
Learn more about Sliding Window patterns.
Solution Approach
The solution approach described can be implemented through the following steps and considerations:
-
Array
f
Initialization: We start by initializing an arrayf
wheref[i]
represents the length of the increasing consecutive subsequence that ends at indexi
ofnums
. Initially, each entry inf
is set to1
because the smallest possible increasing subsequence includes the element itself.f = [1] * n # Where n is the length of nums
-
Constructing the
f
Array: We iterate through thenums
array starting from index1
ton-1
. The comparison conditionnums[i] == nums[i - 1] + 1
is checked to determine if the current number continues the ascending sequence with the previous number. If true, we incrementf[i]
byf[i - 1] + 1
; otherwise, it remains1
.for i in range(1, n): if nums[i] == nums[i - 1] + 1: f[i] = f[i - 1] + 1 else: f[i] = 1
-
Building the Results: We create a list comprehension to build the resulting array. The iteration starts from
k - 1
ton
, checking iff[i]
is at leastk
. If the condition holds, the power (maximum element) isnums[i]
since it represents the end of a valid k-length consecutive subsequence. If not, we place-1
to indicate the subarray doesn’t qualify.results = [nums[i] if f[i] >= k else -1 for i in range(k - 1, n)]
-
Return the Results: The final step involves returning the
results
array, capturing the power of each valid subarray of sizek
.
The overall approach efficiently processes the array with a single pass to determine consecutive subsequences and leverages this information to quickly evaluate each subarray's power, maintaining an optimal time complexity.
Ready to land your dream job?
Unlock your dream job with a 2-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's consider a small example to illustrate the solution approach:
Suppose we have an array nums = [3, 4, 5, 6, 1, 2]
and k = 3
.
Step 1: Auxiliary Array Initialization
We initialize an auxiliary array f
with the same length as nums
, where each element is set to 1
. This array will help track the lengths of increasing consecutive subsequences ending at each index in nums
.
f = [1, 1, 1, 1, 1, 1]
Step 2: Constructing the f
Array
Now, we iterate through nums
starting from index 1
:
- At index
1
,nums[1] = 4
andnums[0] = 3
. Since4
is3 + 1
, we incrementf[1] = f[0] + 1 = 2
, resulting inf = [1, 2, 1, 1, 1, 1]
. - At index
2
,nums[2] = 5
andnums[1] = 4
. Since5
is4 + 1
, we incrementf[2] = f[1] + 1 = 3
, resulting inf = [1, 2, 3, 1, 1, 1]
. - At index
3
,nums[3] = 6
andnums[2] = 5
. Since6
is5 + 1
, we incrementf[3] = f[2] + 1 = 4
, resulting inf = [1, 2, 3, 4, 1, 1]
. - At index
4
,nums[4] = 1
andnums[3] = 6
. Since1
is not6 + 1
, we resetf[4] = 1
, resulting inf = [1, 2, 3, 4, 1, 1]
. - At index
5
,nums[5] = 2
andnums[4] = 1
. Since2
is1 + 1
, we incrementf[5] = f[4] + 1 = 2
, resulting inf = [1, 2, 3, 4, 1, 2]
.
Step 3: Building the Results
We construct a list comprehension to build the results
array. The iteration starts from k - 1
(which is 2
for our example) to n
:
- At index
2
,f[2] = 3
which is greater than or equal tok
, soresults[0] = nums[2] = 5
. - At index
3
,f[3] = 4
which is greater than or equal tok
, soresults[1] = nums[3] = 6
. - At index
4
,f[4] = 1
which is less thank
, soresults[2] = -1
. - At index
5
,f[5] = 2
which is less thank
, soresults[3] = -1
.
results = [5, 6, -1, -1]
Step 4: Return the Results
Finally, we return the results
array, which is [5, 6, -1, -1]
, representing the power of each k-sized subarray of nums
.
Solution Implementation
1from typing import List
2
3class Solution:
4 def resultsArray(self, nums: List[int], k: int) -> List[int]:
5 n = len(nums)
6 f = [1] * n # Initialize an array to keep track of consecutive sequences
7
8 # Iterate through the list and record the length of consecutive increasing sequences
9 for i in range(1, n):
10 if nums[i] == nums[i - 1] + 1:
11 f[i] = f[i - 1] + 1
12
13 # Build the result array with elements meeting the required sequence length, rest are -1
14 return [nums[i] if f[i] >= k else -1 for i in range(k - 1, n)]
15
1import java.util.Arrays;
2
3class Solution {
4 public int[] resultsArray(int[] nums, int k) {
5 int n = nums.length;
6 int[] f = new int[n]; // Array to store lengths of consecutive subarrays
7 Arrays.fill(f, 1); // Initialize all elements in f to 1
8
9 // Build the 'f' array by checking for consecutive numbers
10 for (int i = 1; i < n; ++i) {
11 if (nums[i] == nums[i - 1] + 1) {
12 f[i] = f[i - 1] + 1; // Increment length if consecutive
13 }
14 }
15
16 int[] ans = new int[n - k + 1]; // Array to store results
17 // Fill the result array with either the last number of a valid subarray or -1
18 for (int i = k - 1; i < n; ++i) {
19 ans[i - k + 1] = f[i] >= k ? nums[i] : -1;
20 }
21
22 return ans;
23 }
24}
25
1#include <vector>
2
3class Solution {
4public:
5 std::vector<int> resultsArray(std::vector<int>& nums, int k) {
6 int n = nums.size();
7
8 // Array to store the length of consecutive increasing subsequence ending at each index
9 int consecutiveLengths[n];
10 consecutiveLengths[0] = 1; // Initializing the first element's length as 1
11
12 // Calculate the length of consecutive increasing subsequences
13 for (int i = 1; i < n; ++i) {
14 if (nums[i] == nums[i - 1] + 1) {
15 consecutiveLengths[i] = consecutiveLengths[i - 1] + 1; // Increase length if consecutive
16 } else {
17 consecutiveLengths[i] = 1; // Reset length if not consecutive
18 }
19 }
20
21 std::vector<int> ans; // Vector to store the final results
22
23 // Determine which elements are valid according to the condition
24 for (int i = k - 1; i < n; ++i) {
25 if (consecutiveLengths[i] >= k) {
26 ans.push_back(nums[i]); // Element is valid, append to the result
27 } else {
28 ans.push_back(-1); // Element does not meet the requirement, append -1
29 }
30 }
31
32 return ans;
33 }
34};
35
1// This function takes an array of numbers `nums` and an integer `k`, returning an array of numbers.
2function resultsArray(nums: number[], k: number): number[] {
3 const n = nums.length; // Store the length of the input array.
4
5 // Initialize an array `f` filled with 1s, where `f[i]` keeps track of consecutive elements.
6 const f: number[] = Array(n).fill(1);
7
8 // Iterate through `nums` starting from the second element.
9 for (let i = 1; i < n; ++i) {
10 // Check if the current element is consecutive to the previous.
11 if (nums[i] === nums[i - 1] + 1) {
12 // Increment the current position by previous count if consecutive.
13 f[i] = f[i - 1] + 1;
14 }
15 }
16
17 // Result array `ans` to store the desired output.
18 const ans: number[] = [];
19
20 // Start from the (k-1)th element since we need at least k elements in a sequence.
21 for (let i = k - 1; i < n; ++i) {
22 // If the length of consecutive numbers ending at `i` is at least `k`, include `nums[i]`.
23 // Otherwise, include `-1`.
24 ans.push(f[i] >= k ? nums[i] : -1);
25 }
26
27 // Return the constructed result array.
28 return ans;
29}
30
Time and Space Complexity
The time complexity of the provided code is O(n)
. This is because the algorithm involves iterating over the array nums
twice. The first loop computes the values in the auxiliary array f
for each element, resulting in a linear pass over the input of size n
. The second loop creates the result using these values, also covering the entire array once.
The space complexity is O(n)
. This is due to the storage of the auxiliary array f
, which holds an integer for each element in nums
, leading to a total space requirement proportional to the input size.
Learn more about how to find time and space complexity quickly.
How does merge sort divide the problem into subproblems?
Recommended Readings
https algomonster s3 us east 2 amazonaws com cover_photos stack svg Sliding Window Maximum Monotonic Stack We have an array and a sliding window defined by a start index and an end index The sliding window moves from left of the array to right There are always k elements in
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https algomonster s3 us east 2 amazonaws com recursion jpg You first
Want a Structured Path to Master System Design Too? Don’t Miss This!