双端队列动画演示

两头都能进出,滑动窗口的最大值靠它压成单调。

键盘:← → 单步 ·空格 播放/暂停 · R 重置 ·Home/End 到两端

双端队列把队列的两端都打开:能 pushFront 也能 popBack,于是它同时是队列和栈。页面上半段就四种操作轮着来,注意每格的位次标注会随队首插入整体挪动,动的是指针关系而不是数据搬运。定长数组实现时它同样要绕回,只是两个方向的边界都要算。

下半段是它最有价值的用法:滑动窗口最大值。窗口每次右移一格,直接扫一遍是 O(n·k)。把窗口里候选的下标放进双端队列,并保证从队首到队尾对应的值严格递减——新值进来时,队尾那些比它小又比它先过期的下标再没机会当选,一次性从队尾弹掉。这样队首就是当前窗口的最大值,每个下标进出各一次,总代价降到 O(n)。

双端队列演示怎么用

  • 分两段看:前一半只有「双端队列本体」那行在动,是纯粹的四端操作;后一半才启用输入数组、单调队列与答案三行,两段时间上接在同一条播放轴上。
  • 调窗口长度:窗口 k 从 2 到 5,改一次整段重跑。数组形态选递增时每一轮都会把队尾弹空,选递减时几乎不弹,靠队首过期。
  • 看 tags:输入数组这一行的两个标签标出当前窗口的左右端,单调队列那行只放下标——放值就不知道有没有滑出窗口了。
  • 对答案:最后一步把窗口结果和暴力重扫的答案放在一起比,两者一致才继续,这是这一页自带的自检。

常见问题

为什么队里存下标而不是存值?

因为要判断队首有没有滑出窗口,只看值无法知道它是第几个进来的。存下标之后,过期条件写成 dq.front < i-k+1 一句就够了,取最大值时再用下标回数组查值。

相等的元素为什么也要从队尾弹掉?

新下标比旧下标活得久,值又相同,旧的那个当选不了任何窗口的最大值,留着只会多比一次。弹掉不影响答案,还能让队列严格递减,逻辑更干净。

双端队列还能干什么?

单调队列家族都能:窗口最小值、柱状图里每个矩形的左右边界、题目里要求「两端都能塞」的构造。另外它是浏览器缓存淘汰的实现底座——两端进出配哈希表定位。

演示编号 B03无需安装,手机端同样可用按 Ctrl + K 搜工具与演示