单调队列详解[C/C++]

单调队列

前言

单调队列主要还是一个队列, 組队列里面的元素值满足单调性,一般配合 动态规划进行问
题的优化。

一、滑动窗口

1、引例

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

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

  • 1 <= nums.length <= 105
  • -104 <= nums[i] <= 104
  • 1 <= k <= nums.length

朴素做法

以我们朴素的思维,我们会想到维护这个窗口,每向右滑动一次,就计算一次最值,计算最值时间复杂度为O(k),滑动结束的时间复杂度为O(n),总的时间复杂度为O(N * k),而根据这道题1e5的数据量,显然会超时

ST表/线段树解决区间最值

这其实是一个经典的区间最值问题,我们可以用稀疏(ST,Sparse Table)表来求解,时间复杂度为O(n logk),也可以用线段树来求解区间最值,时间复杂度也是O(n logk)

设计数据结构

本文着重介绍的是一种O(n)的算法,它基于数据结构——单调队列。

对于滑动窗口向右滑动一次其实只出队了一个元素,进队了一个元素,不过相差了两个元素而已。

单调队列详解[C/C++]_第1张图片

如果我们有一种容器,该容器能够支持:

1、O(1)时间获取容器中最大元素

2、O(1)时间删除元素

3、O(1)时间插入元素

你可能感兴趣的:(c语言,c++,java)