leetcode239. Maximum sliding window (monotonic queue or heap)

topic

Given an integer array nums, there is a sliding window of size k that moves from the leftmost side of the array to the rightmost side of the array. You can only see the k numbers in the sliding window. The sliding window only moves one position to the right at a time.

Returns the maximum value in the sliding window.

Example 1

输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置                最大值
---------------               -----
[1  3  -1] -3  5  3  6  7       3
 1 [3  -1  -3] 5  3  6  7       3
 1  3 [-1  -3  5] 3  6  7       5
 1  3  -1 [-3  5  3] 6  7       5
 1  3  -1  -3 [5  3  6] 7       6
 1  3  -1  -3  5 [3  6  7]      7

Monotonic queue solution

Monotonic queue

void push_front(n)//在队头插入n
void push_back(n)//在队尾插入n
void pop_front()//删除队首元素
void pop_back()//删除队尾元素
int front()
int back()

I declared a variable deque<int>windowto store the subscript. This variable has the following characteristics:

  • The front end of the variable (that is, window.front()) is the subscript of the maximum value of this traversal
  • When we encounter a new number, we compare the new number with the end of the two-item queue (ie window.back()). If the end is smaller than the new number, the end is thrown away until the end of the queue is newer Stop only when the number is large or the queue is empty. The approach is a bit like using the stack to match parentheses.
  • All values ​​in the deque must be within the window range

The first feature is that it is convenient for us to get the maximum value after each window sliding one grid, we can get it directly through window.front()

Through feature two, it can be ensured that the elements in the queue are in descending order from beginning to end. Since there are only numbers in the window in the queue, they are actually the first, second, third... numbers in the window.

Feature three is set according to the meaning of the question. But we actually just compare the current subscript with window.front(), think about why?

Answer: Because as long as the first element in the window is the window.front() in the window, then we don't care whether the second and third elements are in the range. Because the answer must be the number one element. If window.front() is not in the window, it will be popped up, the second largest element becomes the first largest element, the third largest element becomes the second largest element, and so on.

The process of writing code should always check whether the queue is empty to prevent throwing exceptions.

time complexity

Insert picture description here

Code

vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        int n=nums.size();
		deque<int>q;
		for(int i=0;i<k;++i)//i表示滑动窗口的最右侧下标 
		{
			while(!q.empty()&&nums[i]>nums[q.back()])
				q.pop_back();
			q.push_back(i);
		}
		vector<int>result; 
		for(int i=k;i<n;++i)//i表示滑动窗口的最右侧下标 
		{
			while(!q.empty()&&nums[i]>nums[q.back()])
				q.pop_back();
			q.push_back(i);
			if(q.front()<=i-k)
				q.pop_front();
			result.push_back(nums[q.front()]);
		} 
    }

Guess you like

Origin blog.csdn.net/weixin_45019830/article/details/115311278