Skip to content

[剑指 Offer] 59 - I. 滑动窗口的最大值 #84

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
frdmu opened this issue Aug 18, 2021 · 0 comments
Open

[剑指 Offer] 59 - I. 滑动窗口的最大值 #84

frdmu opened this issue Aug 18, 2021 · 0 comments

Comments

@frdmu
Copy link
Owner

frdmu commented Aug 18, 2021

给定一个数组 nums 和滑动窗口的大小 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

提示:

  • 你可以假设 k 总是有效的,在输入数组不为空的情况下,1 ≤ k ≤ 输入数组的大小。

解法一:
优先队列。这道题不难,但是用暴力法,会超时。代码如下:

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        int n = nums.size();
        if (n == 0) return {};
        vector<int> res;
        priority_queue<pair<int, int>> q;

        for (int i = 0; i < k; i++) {
            q.push(make_pair(nums[i], i));
        }
        res.push_back(q.top().first);
        for (int right = k; right < n; right++) {
            q.push(make_pair(nums[right], right));
            while (q.top().second <= right-k) {
                q.pop();
            }    
            res.push_back(q.top().first);
        }

        return res;
    }
};

解法二:
单带队列。用双端队列实现。代码如下:

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        int n = nums.size();
        if (n == 0) return {};
        
        vector<int> res;
        deque<int> q;
        for (int i = 0; i < k; i++) {
            while (!q.empty() && nums[i] >= nums[q.back()]) {
                q.pop_back();
            }
            q.push_back(i);
        }
        res.push_back(nums[q.front()]);
        for (int right = k; right < n; right++) {
            while (!q.empty() && nums[right] >= nums[q.back()]) {
                q.pop_back();
            }
            q.push_back(right);
            while (!q.empty() && q.front() <= right-k) {
                q.pop_front();
            }
            res.push_back(nums[q.front()]);
        }


        return res;
    }
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant