Asked 3 months ago
0Comments
6 Views
You're given an array of integers, nums
, and a sliding window of size k
that moves from the very left of the array to the very right. At each step, you can only see the k
numbers within the window. The window slides one position to the right each time.
Your Task:
Return an array containing the maximum value in each sliding window.
Imagine you're driving along a straight road with gas stations (think of them as positions in the array). You have a window (of size k
) that shows a fixed number of gas stations at a time. As you move forward (slide the window), you want to know the maximum gas available in your current view.
But instead of gas, we're dealing with numbers, and we want to find the maximum number within each window as it slides through the array.
The simplest way to solve this problem is to:
k
.#include <vector>
#include <algorithm>
using namespace std;
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> result;
int n = nums.size();
for(int i = 0; i <= n - k; ++i){
// Extract the window
vector<int> window(nums.begin() + i, nums.begin() + i + k);
// Find the maximum in the window
int max_val = *max_element(window.begin(), window.end());
// Store it
result.push_back(max_val);
}
return result;
}
};
Inefficient for large datasets.
Time Complexity: O(n×k)O(n \times k)
For each of the n−k+1n - k + 1 windows, you're performing a kkk-length scan to find the maximum.
Given the constraints (especially nums.length
up to 10^5),
the naive approach becomes too slow. We need something more efficient—preferably O(n) time complexity.
To achieve O(n) time complexity, we need a way to:
A deque (double-ended queue) is perfect for this. Here's why:
nums
.i - k + 1
).Let's walk through Example 1 to visualize the process.
nums = [1,3,-1,-3,5,3,6,7]
, k = 3
[3,3,5,5,6,7]
i | nums[i] | Deque Contents (Indices) | Current Window | Max in Window | Result |
---|---|---|---|---|---|
0 | 1 | [0] | [1] | - | - |
1 | 3 | [1] | [1,3] | - | - |
2 | -1 | [1,2] | [1,3,-1] | 3 | [3] |
3 | -3 | [1,2,3] | [3,-1,-3] | 3 | [3,3] |
4 | 5 | [4] | [-3,5,3] | 5 | [3,3,5] |
5 | 3 | [4,5] | [5,3,6] | 5 | [3,3,5,5] |
6 | 6 | [6] | [3,6,7] | 6 | [3,3,5,5,6] |
7 | 7 | [7] | [6,7] | 7 | [3,3,5,5,6,7] |
Explanation:
Indices 0 to 2:
[1,3,-1]
.[1,2]
because 3
(index 1) is larger than 1
, and -1
(index 2) is less than 3
.3
.Index 3:
[3,-1,-3]
.-3
is added; deque becomes [1,2,3]
.3
(index 1).Index 4:
[-1,-3,5]
.1
, 2
, and 3
as 5
is larger.[4]
.5
.Index 5:
[-3,5,3]
.5
; deque becomes [4,5]
.5
(index 4).Index 6:
[5,3,6]
.5
because 6
is larger.[4,6]
.6
.Index 7:
[3,6,7]
.4
because 7
is larger.[7]
.7
.#include <vector>
#include <deque>
using namespace std;
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
deque<int> dq; // Stores indices
vector<int> ans; // Stores the maximums
// Process the first 'k' elements
for (int i = 0; i < k; i++) {
// Remove elements from the back that
// are smaller than the current element
while (!dq.empty() && nums[i] >= nums[dq.back()]) {
dq.pop_back();
}
// Add current index to the back
dq.push_back(i);
}
// The front of the deque has the index of the
// largest element for the first window
ans.push_back(nums[dq.front()]);
// Process the remaining elements
for (int i = k; i < nums.size(); i++) {
// Remove the front element if it's outside the current window
if (!dq.empty() && i - dq.front() >= k) {
dq.pop_front();
}
// Remove elements from the back that are smaller
// than the current element
while (!dq.empty() && nums[i] >= nums[dq.back()]) {
dq.pop_back();
}
// Add current index to the back
dq.push_back(i);
// The front of the deque has the index of the
// largest element for the current window
ans.push_back(nums[dq.front()]);
}
return ans;
}
};
Initialize a Deque and Result Vector:
deque<int> dq;
vector<int> ans;
Process the First Window (First 'k' Elements):
for (int i = 0; i < k; i++) {
while (!dq.empty() && nums[i] >= nums[dq.back()]) {
dq.pop_back();
}
dq.push_back(i);
}
nums
values.nums[i]
) with the Last Element in Deque (nums[dq.back()]
):nums[i]
is greater or equal, pop the last index since nums[i]
could be a potential maximum for future windows.ans.push_back(nums[dq.front()]);
Why ! The Reason ! ? :
Because ! The front of the deque (dq.front()
) holds the index of the maximum element for the first window.
for (int i = k; i < nums.size(); i++) {
// Remove indices outside the current window
if (!dq.empty() && i - dq.front() >= k) {
dq.pop_front();
}
// Remove elements smaller than the current element from the back
while (!dq.empty() && nums[i] >= nums[dq.back()]) {
dq.pop_back();
}
// Add current index to the deque
dq.push_back(i);
// Add the current maximum to the result
ans.push_back(nums[dq.front()]);
}
Steps Happening in this code block ! :
nums
values are less than or equal to nums[i]
.---------------------------------------------------------------------------------------------------------------------------------------------
Monotonic Deque:
The deque maintains indices in a monotonically decreasing order of their corresponding nums
values. This means:
nums[i]
) is removed because it cannot be the maximum in the presence of a larger element.Efficiency:
k
elements.Share