数据结构——单调队列

单调队列

        单调队列的概念和操作过程

        概念:

        单调队列和单调栈在操作上有相似之处,但因为单调队列是队列,所以多了一项特殊操作,即头部的元素可以出队,相当于滑动窗口向后滑动。这头部的出队操作就相当于淘汰,用以维护窗口的滑动。

以下通过图片来解释单调队列的操作:

        继续入队,直到入队索引2元素时,违反了队列里的单调性:

        现在就需要将违反单调性的元素进行从对位剔除,也就是tail指针向前,直到到不违反单调性或者与head指针相同;

        然后入队索引2元素:

        现在入队索引3,然后又违反了单调性,剔除索引2,入队索引3:

        由于上面没有发生淘汰的过程,我就没有说从头部淘汰的过程,现在经过操作到达图中情况:

        现在索引在6的位置,头部索引在3,6 - 3 = 3 = k,那么就需要从头部淘汰索引3的元素,那头指针向后移动一个,这就是淘汰的操作:

        那么整个的单调队列的操作,就是这样最终队列应该是这样:

单调队列的作用:  

单调队列的主要作用是在处理数据序列中,帮助解决需要维护一定单调性的问题,通常是查找滑动窗口内的最大或最小值。其作用包括:

  1. 查找滑动窗口内的最大值或最小值:单调队列可以在O(1)的时间复杂度内获取当前滑动窗口的最大值或最小值,而不需要遍历整个窗口,这在实时数据处理中非常有用。

  2. 优化数据流处理:当需要实时处理数据流并获取特定窗口内的信息时,单调队列可以提供高效的解决方案,减少不必要的计算和遍历。

  3. 优化某些动态规划问题:在一些动态规划问题中,需要维护满足特定条件的一系列元素,单调队列可以帮助高效地实现这种要求。

  4. 解决其他需要维护单调性的问题:除了滑动窗口问题,单调队列还可用于解决其他需要维护单调性的问题,如找到数组中连续子数组的最大或最小值。

总之,单调队列的主要作用是通过维护一个队列,使其中的元素保持一定单调性,以提高特定问题的解决效率,尤其在需要实时处理数据流或窗口数据的情况下,它具有显著的性能优势。

例题:

        力扣剑指offer59

int* maxSlidingWindow(int* nums, int numsSize, int k, int* returnSize){
    int q[numsSize];//创建队列
    memset(q, 0, sizeof(q));//初始化队列
    int head = 0, tail = 0;//初始化指针
    int *ret = (int *)calloc(sizeof(int), numsSize);//创建返回数组
    int cnt = 0;//记录返回数组元素个数
    for (int i = 0; i < numsSize; i++) {
        while (head != tail && nums[i] >= nums[q[tail - 1]]) tail--;//违反单调性就剔除
        q[tail++] = i;//将当前索引入队
        if (i - k >= q[head]) head++;//当头部元素不在窗口时,淘汰
        if (i < k - 1) continue; //没有达到窗口大小,继续入队
        ret[cnt++] = nums[q[head]];//头部元素就是窗口最大值,维护的是单调递减,所以头部就是最大值,反之就是最小值
    }
    *returnSize = cnt;
    return ret;
}
        这个过程就和上面的过程是完全一样的,只是题目是维护单调递减,而我上面的图片是维护的单调递增,思路都是一模一样的;
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

初猿°

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值