滑动窗口最大值(双向队列)

本文详细介绍了滑动窗口最大值问题的解题思路和代码实现,通过使用双向队列保持滑动窗口内的元素按值有序,从而在每次窗口移动时快速找到最大值。示例展示了在给定整数数组和窗口大小的情况下,如何找到每个窗口的最大值。代码中提供了两种版本,分别是无注释版和注释版,方便理解。

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

 

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

 

 

示例 1:

 

输入: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

 

示例 2:

 

输入:nums = [1], k = 1

输出:[1]

 

解题思路:

把滑动窗口存储在双向队列中(存储下标),刚开始时队列为空,然后让front指针和back指针都指向第一个元素,然后每次入队之前都判断该元素是否大于队尾元素,大于则队尾元素出队,继续判断,也就是将队列从大到小排序,输出滑动窗口最大值时也就是输出队头元素,还需判断队头元素是否在滑动窗口内,不在则队头元素出队。

 

代码实现:

 

// 无注释版

 

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

 

// 注释版

 

class Solution {    // 类实现
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {


    
    vector<int> result;  // 创建要输出的结果数组
    deque<int> deq;    // 创建双向队列

 

// 把每个元素循环一遍
    for(int i=0;i<nums.size();i++) {

 

// 如果队列不为空且队头元素不在滑动窗口内

// 则队头元素出队
    if(!deq.empty()&&deq.front()==i-k)
        deq.pop_front();

 

// 如果队列不为空且该元素大于队尾元素

// 则队尾元素出队,然后继续判断(排序)
    while(!deq.empty()&&nums[i]>=
        nums[deq.back()])
        deq.pop_back();


    deq.push_back(i);   // 把该元素的下标 i 入队

 

// 如果队列等于滑动窗口

// 则把该队列(滑动窗口)的队头元素(最大元素)

// 插入到result中
    if(i>=k-1)
  result.push_back(nums[deq.front()]);   


    }


    return result;    // 返回result


    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值