LeetCode 每日一题 2021-1-2 (滑动窗口最大值 单调队列)

239. 滑动窗口最大值

难度困难

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回滑动窗口中的最大值。

思路一:在滑动窗口内保证为单调队列

单调递减队列:在队列中 假定 num[i] ≥ num[j](其中 i < j )。

在上述单调递减队列中的最大元素一定在队列的左侧。

如何确保单调递减队列:需要采用双向队列(deque) 。

  1. 当前数据小于上一个数据:直接压入队列;
  2. 当前数据大于上一个数据:将队列中小于该数据的全部数据弹出队列; 
  3. 确保队列中的全部数据在当前窗口内;
  4. 当期窗口的最大值为当前单调队列的第一个数据(最早的数据)。

代码

// 单调队列实现 - 双端队列
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
    if(k==1) return nums;;
    int len=nums.size();
    deque<int> data;
    for(int i=0;i<k;++i){
        while(!data.empty() && nums[i]>=nums[data.back()]){
            data.pop_back();
        }
        data.push_back(i);
    }
    vector<int> ans = {nums[data.front()]};
    for(int i=k;i<len;++i){
            while(!data.empty() && nums[i]>=nums[data.back()]){
            data.pop_back();
        }
        data.push_back(i);
        while(data.front()<=i-k){
            data.pop_front();
        }
        ans.push_back(nums[data.front()]);
    }
    return ans;
}

思路二:最大堆实现

采用最大堆实现时将每个数压入最大堆中,同时确保当前最大值在窗口范围内,否则弹出当前最大值。

代码

// 最大堆方式实现
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
    if(k==1) return nums;;
    int len=nums.size();
    priority_queue<pair<int, int>> data;
    vector<int> ans;
    for(int i=0;i<k;++i){
        data.push({nums[i],i});
    }
    ans.push_back(data.top().first);
    for(int i=k;i<len;++i){
        data.push({nums[i],i});
        while(data.top().second <= i-k){
            data.pop();
        }
        ans.push_back(data.top().first);
    }
    return ans;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值