Day4 plus 滑动窗口最大值

1.题目描述

链接:https://leetcode.cn/problems/sliding-window-maximum/description/

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回 滑动窗口中的最大值 

2.示例

输入: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

3.题目解析

优先级队列解法

因为要维护最大值,很容易的我们可以想到优先级队列,每次维护整个窗口的最大值。但是优先级队列需要注意的一个点就是,下标的大小。有可能第二大在窗口左边界的左边,那么这个时候是不能取这个最大值的,因此我们需要删除优先级队列中下标≤left 的节点

这里可以使用priority_queue<pair<int,int>>来维护窗口的最大值

单调栈

单调栈的思想很有意思,利用了一个思想,每次存储靠后下标的最大值,什么意思呢?

比如说 j>= i,同时 nums[j] ≥ nums[i],那么这个时候是不是没有必要维护nums[i]了呢?

答案是 YES,因为 j和i在同一个窗口的时候,一定会有nums[j]为最大值,这个时候就没有必要去考虑nums[i]了,因此在栈中直接在尾部pop掉前面 i≤ j && nums[i]≤ nums[j]的节点

这个时候我们很容易知道 栈的头部就是最大值,但是可能栈的头部已经超过窗口的边界了

因此我们需要弹出栈头部 在左边界的值

so…可以用deque去实现头部和尾部的操作

4.代码实现

优先级队列

class Solution {
public:
	vector<int> maxSlidingWindow(vector<int>& nums, int k) {
		const int N = nums.size();
		vector<int>res;
		//可以维护一个最大堆,每次将堆进行插入和删除
		int left = 0, right = k - 1;
		priority_queue<pair<int, int>>pq;
		for (int i = 0; i <= right; ++i)
			pq.push({ nums[i],i });
		res.emplace_back(pq.top().first);
		++right;
		while (right < N)
		{
			while (!pq.empty() && pq.top().second <= left)
				pq.pop();
			pq.push({ nums[right],right });
			++left, ++right;
			res.emplace_back(pq.top().first);
		}
		return res;
	}
};

单调栈

class Solution {
public:
	vector<int> maxSlidingWindow(vector<int>& nums, int k) {
		const int N = nums.size();
		deque<int>dq;
		vector<int>res;
		int right = 0;
		for (; right < k; ++right)
		{
			while (!dq.empty() && nums[right] >= nums[dq.back()])
				dq.pop_back();
			dq.push_back(right);
		}
		res.push_back(nums[dq.front()]);
		while (right < N)
		{
			while (!dq.empty() && nums[right] >= nums[dq.back()])
				dq.pop_back();
			dq.push_back(right);
			while (dq.front() <= right - k)
				dq.pop_front();
			res.push_back(nums[dq.front()]);
            ++right;
		}
		return res;
	}
};
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇