0% completed
Problem Statement
Given an integer array arr
and an integer k
, return the result
list containing the maximum for each and every contiguous subarray of size k
.
In other words, result[i] = max(arr[0],..., arr[k])
, result[1] = max(arr[1],...arr[k+1])
, etc.
Examples
Example 1
- Input: arr =
[1, 2, 3, 1, 4, 5, 2, 3, 6]
, k =3
- Output:
[3, 3, 4, 5, 5, 5, 6]
- Description: Here, subarray
[1,2,3]
has maximum 3,[2,3,1]
has maximum 3,[3,1,4]
has maximum 4,[1,4,5]
has maximum 5,[4,5,2]
has maximum 5,[5,2,3]
has maximum 5, and[2,3,6]
has maximum 6.
Example 2
- Input: arr =
[8, 5, 10, 7, 9, 4, 15, 12, 90, 13]
, k =4
- Output:
[10, 10, 10, 15, 15, 90, 90]
- Description: Here, the maximum of each subarray of size 4 are 10, 10, 10, 15, 15, 90, 90 respectively.
Example 3
- Input: arr =
[12, 1, 78, 90, 57]
, k =3
- Output:
[78, 90, 90]
- Description: Here, the maximum of each subarray of size 3 are 78, 90, and 90 respectively.
Constraints:
- 1 <= arr.length <= 10<sup>5</sup>
- -10<sup>4</sup> <= arr[i] <= 10<sup>4</sup>
- 1 <= k <= arr.length
Solution
The approach to solve this problem involves utilizing a deque (double-ended queue) to efficiently track the maximum elements in each window of size 'k' as we traverse the array. Initially, we populate the deque with indices of elements, ensuring that it always contains elements in decreasing order. This way, the front of the deque always holds the index of the current maximum element. As we move the window, we add new elements to the rear of the deque, removing those from the front that fall outside the current window. We also remove elements from the rear if they are smaller than the new element being added, as they are no longer potential maximums. This strategy ensures that for each window, we can quickly identify the maximum element, which is always at the front of the deque.
Step-by-Step Algorithm
-
Initialize Data Structures:
- Create a
Deque<Integer>
nameddq
to store indices of array elements. - Create a
List<Integer>
namedresult
to store the maximum values of each sliding window. - Store the length of the input array
arr
in a variablen
.
- Create a
-
Iterate Through the Array:
- Loop through the array
arr
using an indexi
that ranges from0
ton-1
.
- Loop through the array
-
Remove Out-of-Window Elements:
- Inside the loop, first check if there are elements in the
dq
that are out of the current window. The current window is defined as the subarray fromi-k+1
toi
. - If the element at the front of the
deque
is out of this window (i.e.,du.peek() < i - k + 1
), remove it from the front of thedq
usingpoll()
.
- Inside the loop, first check if there are elements in the
-
Remove Useless Elements:
- Next, check if there are any elements in the
dq
that are smaller than the current array elementarr[i]
. This help to maintian the queue elements in decreasing oders, keep the largest element in the current window at the front.. - Remove these smaller elements from the rear of the
dq
usingpollLast()
, as they are not useful for finding the maximum in the current window.
- Next, check if there are any elements in the
-
Add Current Element's Index:
- After cleaning up the
dq
, add the current element's indexi
to the rear of thedq
usingoffer(i)
.
- After cleaning up the
-
Add Maximum to Result List:
- If the index
i
is greater than or equal tok-1
, it means the current window is fully formed. - The element at the front of the
dq
is the maximum of the current window, so addarr[dq.peek()]
to theresult
list.
- If the index
-
Repeat for All Elements:
- Continue this process for all elements in the array.
-
Return the Result:
- After processing all elements, return the
result
list containing the maximum values for each sliding window of sizek
.
- After processing all elements, return the
Algorithm Walkthrough
1 of 9
Code
Here is how we can implement this algorithm:
Complexity Analysis
Time Complexity
-
Single pass through the array: The algorithm processes each element of the array exactly once by iterating over the array in a single pass. This gives us an initial time complexity of O(N), where
N
is the length of the array. -
Deque operations:
- Each element is added to the deque once and removed from the deque at most once. Therefore, all enqueue (offer) and dequeue (poll) operations are done in constant time, O(1), per element.
- The
while
loops inside the iteration only remove elements from the deque in constant time per iteration. Since each element is processed once and added/removed only once from the deque, the total number of deque operations is O(N).
-
Therefore, the overall time complexity of the algorithm is O(N).
Overall time complexity: O(N).
Space Complexity
-
Deque space: The deque stores indices of array elements. At most, it will store
k
elements (since it only keeps track of elements in the current window of sizek
), so the space complexity for the deque is O(k). -
Result list: The result list stores the maximum of each sliding window, which requires O(N - k + 1) space (where
N - k + 1
is the number of windows). This is equivalent to O(N) in the worst case.
Overall space complexity: O(N).
.....
.....
.....
Table of Contents
Contents are not accessible
Contents are not accessible
Contents are not accessible
Contents are not accessible
Contents are not accessible