5星难度滑动窗口最大值
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
示例 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
示例 2:
输入:nums = [1], k = 1
输出:[1]
想法一:我们首先是想到我们定义一个快慢指针来解决滑动窗口的问题,但是还要比较这其中的最大值的时候,就会出现问题,若如下的写法会出现超时的问题:
class Solution { public: int maxnum(vector<int>& nums,int slow,int fast) {//因为这里用到了暴力方法,这导致原来的程序的时间复杂度直接上升为o(n*k),上交力扣的时候会超时的 int max = nums[slow]; for (; slow <= fast; slow++) { if (nums[slow] >= max) { max = nums[slow]; } } return max; } vector<int> maxSlidingWindow(vector<int>& nums, int k) { int slow = 0; int fast = k-1; int max; vector<int>st; if (k > nums.size()) { fast = nums.size()-1; } for (; fast < nums.size(); fast++) { max = maxnum(nums,slow,fast); st.push_back(max); slow++; } return st; } };
想法二:我们需要想办法解决这个滑动的窗口最大值的方法,但是不能直接用暴力对比,这时想到了单调结构,这里可以用到一个单调的双端数组;
class simplequeue { public: deque<int>qu; void push(int a) { while (!qu.empty() && a > qu.back()) {//这里的>还是>=的问题也是很大的,因为要维护前两个最大值,还要排除这个最大值是第一个元素 qu.pop_back(); } qu.push_back(a); } void pop(int a) { if (!qu.empty() && a == qu.front()) { qu.pop_front(); } } int maxi() { return qu.front(); } }; class Solution { public: vector<int> maxSlidingWindow(vector<int>& nums, int k) {//实时模拟一下这个过程就可以明白了,这个单调队列很重要 simplequeue op; int slow = 0; int fast = k; int max; vector<int>st; if (k > nums.size()) { fast = nums.size()-1; } for (int i = 0; i < k; i++) { op.push(nums[i]); } st.push_back(op.qu.front()); for (; fast < nums.size(); fast++) { op.pop(nums[slow]); op.push(nums[fast]); st.push_back(op.qu.front()); slow++; } return st; } };
【推荐】FlashTable:表单开发界的极速跑车,让你的开发效率一路狂飙
【推荐】Flutter适配HarmonyOS 5知识地图,实战解析+高频避坑指南
【推荐】博客园的心动:当一群程序员决定开源共建一个真诚相亲平台
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步