leetcode 239 滑动窗口最大值
作者:互联网
不大会做,一看题解果然要用到别的数据结构。第一种方法用的是优先队列,也就是大顶堆。其中一个很好的想法是,在滑动窗口移动的时候,添加后方的元素,但是不着急删除前一个元素。而在判断最大值时,如果最大值所在的索引不在窗口内,则弹出该最大值,并重复这一段操作,直到当前最大值在窗口内。贴第一种方法
1 class Solution { 2 public: 3 vector<int> maxSlidingWindow(vector<int>& nums, int k) 4 { 5 vector<int> resVec; 6 priority_queue<pair<int,int>> que; 7 for(int i = 0 ; i < k ; i++) 8 que.emplace(nums[i],i); 9 resVec.push_back(que.top().first); 10 for(int i = k ; i < nums.size() ; i++) 11 { 12 que.emplace(nums[i],i); 13 while(que.top().second<=i-k) 14 que.pop(); 15 resVec.push_back(que.top().first); 16 } 17 return resVec; 18 } 19 };
可以顺着这个思路进行改进。考虑某一种情况,当滑动窗口向后移动时,如果新添加的元素b大于添加之前的最后一位元素a,那就代表,如果如果a在窗口内,那么b肯定在窗口内,并且由于b大于a,则a不可能是最大值,于是就可以将a删除,之后继续进行上述操作,直到原始空间为0或者出现大于b的元素。基于上述推理,可以用一个双向队列来存放某一窗口期的下标。在完成操作后,双向队列中元素一定是单调递减的。从而可以进行最大值的选取,当前队列头即是最大值,但也需要判断最大值是否在窗口内,由此就完成了选取。贴代码
1 class Solution { 2 public: 3 vector<int> maxSlidingWindow(vector<int>& nums, int k) 4 { 5 vector<int> resVec; 6 int n = nums.size(); 7 deque<int> que; 8 for(int i = 0 ; i < k ; i++) 9 { 10 while(!que.empty() && nums[i]>=nums[que.back()]) 11 que.pop_back(); 12 que.push_back(i); 13 } 14 resVec.push_back(nums[que.front()]); 15 for(int i = k ; i < n ; i++) 16 { 17 while(!que.empty() && nums[i]>=nums[que.back()]) 18 que.pop_back(); 19 que.push_back(i); 20 while(que.front()<=i-k) 21 que.pop_front(); 22 resVec.push_back(nums[que.front()]); 23 } 24 return resVec; 25 } 26 };
还有一种方法,分治法,某一个窗口的最大值可以分为两部分,前缀部分与后缀部分。而这两部分的分界线就是当前位置索引是否是k的倍数。后缀同样有迭代公式,若n为k的倍数,则以当前节点结尾的前缀最大值就是当前节点值,若不是,则是前一节点结尾的前缀最大值和当前值的较大值。后缀有类似的递推。贴代码
1 class Solution { 2 public: 3 vector<int> maxSlidingWindow(vector<int>& nums, int k) 4 { 5 vector<int> resVec; 6 int n = nums.size(); 7 vector<int> prefixMax(n),suffixMax(n); 8 for(int i = 0 ; i < n ; i++) 9 { 10 if(i%k == 0) 11 prefixMax[i] = nums[i]; 12 else 13 prefixMax[i] = max(prefixMax[i-1],nums[i]); 14 } 15 for(int i = n-1 ; i >= 0 ; i--) 16 { 17 if(i == n-1 || (i+1)%k == 0) 18 suffixMax[i] = nums[i]; 19 else 20 suffixMax[i] = max(suffixMax[i+1],nums[i]); 21 } 22 for(int i = 0 ; i <= n-k ; i++) 23 resVec.push_back(max(suffixMax[i],prefixMax[i+k-1])); 24 return resVec; 25 } 26 };
标签:nums,int,最大值,back,vector,que,239,leetcode 来源: https://www.cnblogs.com/zhaohhhh/p/15364820.html