求滑动窗口内的最大值:朴素法每窗口扫 k 个元素 O(nk)。单调队列维护"下标递增、值递减"的双端队列——新元素从队尾入队前,把所有比它小的队尾元素弹出(它们不可能再成为任何后续窗口的最大值);队首下标超出窗口范围则弹出。每个元素至多进出各一次,整体 O(n)。
窗口最大值。示例代码如下:
local function maxSliding(nums, k)
local dq, out = {}, {}
for i = 1, #nums do
while #dq > 0 and nums[dq[#dq]] <= nums[i] do
table.remove(dq)
end
dq[#dq + 1] = i
if dq[1] <= i - k then
table.remove(dq, 1)
end
if i >= k then
out[#out + 1] = nums[dq[1]]
end
end
return out
end
print(table.concat(maxSliding({ 4, 2, 7, 1, 5 }, 3), ","))
输出 7,7,5——三个窗口的最大值一次线性扫描全部得出。
战场曲线接线。示例代码如下:
local peaks = maxSliding(hourlyKills, 24)
print("沙巴克战场 24 小时击杀峰值 " .. peaks[#peaks])
按小时击杀数取任意 24 小时窗口的峰值——运营看趋势峰值不再全量重算。
朴素法 1000 点、窗口 100:约 9 万次比较 0.5 毫秒;单调队列每元素至多进出各一次约 2000 次操作 0.02 毫秒,快 25 倍。队列内存峰值 O(k)(窗口宽度),100 宽约 400 字节。
三个不适用场景:一是需要任意区间(非定宽滑动)的最值查询,线段树更合适;二是数据流式到达且窗口回溯重算频繁,队列重建成本上升;三是只需要全局最大值,一次 max 遍历即可,无需队列。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
【语法】 一、隐蔽陷阱 对比两份任务记录的"共同路线":要求连续的子串可以逐位比对,允许跳过中间步骤的最长公共子序列却没法直…
【游戏】 一、业务场景 新玩家出门就挨打,图文教学没人看,第二天流失率居高不下。训练营上线:三个分阶关卡(走位、连招、节奏)…
【语法】 一、隐蔽陷阱 五只猴子分桃,每来一只把桃分成 5 份多 1 个扔掉再拿走一份。正向从 1 个桃开始试,试到几千个才…
【游戏】 一、业务场景 满级玩家装备毕业后一周流失,进度条走到头没了盼头。渡劫玩法上线:80 级可挑战三重天劫,全通获得渡劫…
【语法】 一、隐蔽陷阱 63 分找零用面额 1、5、10、25 的硬币,贪心取最大面额 6 枚搞定;可换成面额 1、3、4 …
【游戏】 一、业务场景 会长每天手动发福利、清名单、盯报名,帮务占满游戏时间,连着三周漏发福利被帮众催。帮会管家上线:每周 …