LeetCode 239:滑动窗口最大值 思考分析
給定一個數組 nums,有一個大小為 k 的滑動窗口從數組的最左側移動到數組的最右側。你只可以看到在滑動窗口內的 k
個數字。滑動窗口每次只向右移動一位。
返回滑動窗口中的最大值。
進階:
你能在線性時間復雜度內解決此題嗎?
示例:
輸入: 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
提示:
1 <= nums.length <= 10^5
-10^4 <= nums[i] <= 10^4
1 <= k <= nums.length
暴力求解:超時
class Solution { public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {int maxnum=-10001;vector<int> result;int n= nums.size();//1、如果k> = nums.size, if(k>=n){for(int i=0;i<n;i++){if(nums[i]>=maxnum) maxnum=nums[i];}result.push_back(maxnum);return result;}//2、如果k<nums.sizeelse{int left=0;int right=0;for(left = 0;left<=n-k;left++){//更新左右邊界right=left+k-1;//更新最小值maxnum=-10001;for(int x=left;x<=right;x++){if(nums[x]>=maxnum) maxnum=nums[x]; }result.push_back(maxnum);}return result;}} };優化思路:
可以想到暴力方法肯定是有時間浪費的,在滑窗移動的時候,滑窗內插入一個新值,消失了一個舊值,有k-1個值仍然保留著。
我們只需要比較一下新插入的值和舊的k-1個值中的最大值,將得到的最大值賦給結果數組就可以了。
一開始我想的是用兩個容量為2的數組,分別存放第一大的數值和它的下標,第二大的數值和它的下標,但是在推導的時候發現一個問題:
錯誤代碼,具體疑問見代碼注釋:
發現需要構建一個從大到小排列的雙端隊列;
1、新的數入隊列,并按照其大小排列,然后將比它小的數全部出隊列(因為我們需要的是最大值,只要隊列中有數比新入隊列的數要小就說明它們絕對不可能是最大值,最大值最起碼也是大于等于新入隊列的數)。
2、觀察隊首(數值最大)的索引值是否在[left,right]之間,如果不在就出隊列,直到隊首索引值滿足在[left,right]之間
雖然AC了,但是效率不高,不過基本思路是符合大眾的:
不過上述的寫法仍然有些不簡潔,這里貼一下比較簡潔的寫法:
https://leetcode-cn.com/problems/sliding-window-maximum/solution/dan-diao-dui-lie-by-labuladong/
官方給出的dp思路,還得理解理解
https://leetcode-cn.com/problems/sliding-window-maximum/submissions/
為什么:兩數組一起可以提供兩個塊內元素的全部信息。
考慮從下標 i 到下標 j的滑動窗口。 根據定義,right[i] 是左側塊內的最大元素, left[j] 是右側塊內的最大元素。因此滑動窗口中的最大元素為 max(right[i], left[j])
總結
以上是生活随笔為你收集整理的LeetCode 239:滑动窗口最大值 思考分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 你是礼物剧情介绍
- 下一篇: 剑指 Offer 57 - II. 和为