剑指 Offer 59

思路

方法一:暴力法

遍历每一个数nums[i],之后在[i, i+k]中顺序寻找最大值。

时间复杂度:O(k*n)

 1 class Solution {
 2 public:
 3     vector<int> maxSlidingWindow(vector<int>& nums, int k) {
 4         if(nums.empty()) 
 5             return nums;
 6 
 7         vector<int> res;
 8         for(int i = 0; i <= nums.size()-k; ++i) {
 9             res.push_back(findMax(nums, i, i+k-1));
10         }   
11 
12         return res;
13     }
14 
15     int findMax(vector<int>& nums, int l, int r) {
16         int maxVal = nums[l];
17         for(int i = l+1; i <= r; ++i) {
18             if(maxVal < nums[i])
19                 maxVal = nums[i];
20         }
21 
22         return maxVal;
23     }
24 };

方法二:双端队列

这个方法的思想和 剑指 Offer 30. 包含min函数的栈 中方法一的辅助栈相似。

算法流程:

(1) 对于当前元素num,从双端队列deque的尾部开始判断,把小于num的元素依次pop_back()掉。

(2) 把num添加到deque尾部。

(3) 如果当前元素的位置≥k-1,则把deque队首的元素加入答案数组vector。

(4) 如果num[i-k+1] == deque.front(),则把队首元素pop_front()掉。

 

 1 class Solution {
 2 public:
 3     vector<int> maxSlidingWindow(vector<int>& nums, int k) {
 4         vector<int> res;
 5         deque<int> d;
 6         for(int i = 0; i < nums.size(); ++i) {
 7             while(!d.empty() && d.back() < nums[i])
 8                 d.pop_back();
 9             d.push_back(nums[i]); 
10 
11             if(i >= k-1) {
12                 res.push_back(d.front());
13                 if(d.front() == nums[i-k+1]) {
14                    d.pop_front();
15                 }
16             } 
17         }
18 
19         return res;
20     }
21 
22 };

参考

力扣官方题解 - 滑动窗口最大值

面试题59 - I. 滑动窗口的最大值(单调队列,清晰图解)

相似题目

剑指 Offer 30. 包含min函数的栈

原文地址:https://www.cnblogs.com/FengZeng666/p/13972746.html