双端队列最值结构

文章介绍了如何利用双端队列(deque)有效地解决滑动窗口场景下的最值查找问题。通过维护一个包含元素索引的队列,当窗口向右移动时,新元素根据值插入队列适当位置并删除所有小于新元素的旧元素,保持队列有序。窗口向左移动时,删除队列左侧超出范围的元素。这种方法确保了在常数时间内获取窗口内的最大值或最小值。
摘要由CSDN通过智能技术生成

场景

  • 当遇到滑动窗口场景时,通过双端队列能过迅速找到最值

实现过程

  • 定义双端队列left和right边界,双端队列只存储元素的索引,因为存储索引可以映射到值,比单纯存值具有更多的信息
  • 移动right
    • 初始第一个数值直接放入队列中,后续移动过程中,如果比当前队列中元素都小,直接将对应索引放入队列末尾,否则插入队列中比它小的元素前面(如果值相等,则判断索引更大的在前面),然后删除掉它之后的所有元素(保证索引连续,使得移动left时能放心删除)
  • 移动left
    • 更新双端队列左边界,如果left比队列中的首元素索引要大了,说明当前元素已经不在left和right范围内了,直接弹出删除掉该元素,这也是为什么移动right过程中需要删除掉比插入元素小的所有元素,因为能够保证索引一直是增序,确保删除掉元素后,其他元素一定是在left和right范围内

示例

class Queue {
  arr = [];
  queue = [];
  left = 0;
  right = 0;
  constructor(arr) {
    this.arr = arr;
    this.queue[0] = 0;
  }
  moveOneRightStep() {
    if (this.right < this.arr.length - 1) {
      this.right++;

      const arrNum = this.arr[this.right];
      // 找到第一个比当前 num 小的 queue 中的值
      // 这里也可以 while 每找一个 pop 掉一个
      const index = this.queue.findIndex((i) => this.arr[i] <= arrNum);

      if (index === -1) {
        this.queue.push(this.right);
      } else {
        // 存入当前 num,并删除掉比 num 小的所有值
        this.queue[index] = this.right;
        this.queue.length = index + 1;
      }
    }
  }
  moveOneLeftStep() {
    if (this.left < this.right) {
      this.left++;
      // 移动left,删除掉过期的最大值
      if (this.left > this.queue[0]) {
        this.queue.shift();
      }
    }
  }

  getWindow() {
    return this.queue;
  }

  getRange() {
    return [this.left, this.right];
  }
}

const arr = [5, 2, 3, 7, 4, 5];
const q = new Queue(arr);

q.moveOneRightStep();
q.moveOneRightStep();
q.moveOneRightStep();
q.moveOneRightStep();
q.moveOneRightStep();

q.moveOneLeftStep();
q.moveOneLeftStep();
q.moveOneLeftStep();
// q.moveOneLeftStep();
// q.moveOneLeftStep();

console.log("双端队列索引值", q.getWindow());
console.log("范围", q.getRange());

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值