题目描述
思路解析动画文字版
记住这句:答案藏在「相邻非空桶之间」,桶内差值永远不够大。下面每一帧都在套它。
先定桶:最小 1、最大 9、共 5 个数,算出桶宽 size=2、桶数 5。每个桶只存它见过的最小值和最大值。
看第 0 个数 1(紫色):用 (1-1)/2 算出它该进桶0。
1 落进桶0,这桶刚被点亮,min 和 max 都先记成 1。
看第 1 个数 3(紫色):用 (3-1)/2 算出它该进桶1。
3 落进桶1,这桶刚被点亮,min 和 max 都先记成 3。
看第 2 个数 6(紫色):用 (6-1)/2 算出它该进桶2。
6 落进桶2,这桶刚被点亮,min 和 max 都先记成 6。
看第 3 个数 9(紫色):用 (9-1)/2 算出它该进桶4。
9 落进桶4,这桶刚被点亮,min 和 max 都先记成 9。
看第 4 个数 4(紫色):用 (4-1)/2 算出它该进桶1。
4 也落进桶1,刷新这桶的 min=3、max=4。同桶内差值最多 1,不可能是答案。
所有数都入桶了。现在从左到右扫每个非空桶,只比「上一非空桶的 max」和「当前桶的 min」这一段距离。prev 起步用最小值 1。
轮到非空桶0(紫框)。跨桶间距 = 本桶最小 1 减去上一非空桶的 max 1,得 0。
0 没超过当前最大间距 0,ans 不变。prev 推进到本桶 max 1。
轮到非空桶1(紫框)。跨桶间距 = 本桶最小 3 减去上一非空桶的 max 1,得 2。
2 比之前的最大间距大,刷新 ans=2。再把 prev 推到本桶 max 4,准备比下一个非空桶。
轮到非空桶2(紫框)。跨桶间距 = 本桶最小 6 减去上一非空桶的 max 4,得 2。
2 没超过当前最大间距 2,ans 不变。prev 推进到本桶 max 6。
桶3 是空的(紫框)。空桶直接跳过,不参与比较,prev 保持 6。空桶的存在正说明这里有一道大缝隙。
轮到非空桶4(紫框)。跨桶间距 = 本桶最小 9 减去上一非空桶的 max 6,得 3。
3 比之前的最大间距大,刷新 ans=3。再把 prev 推到本桶 max 9,准备比下一个非空桶。
回头验证:把数排好是 [1, 3, 4, 6, 9],相邻差里最大的正是 3。我们没真排序,只靠扫桶就 O(n) 得到了它。
边界先想清:单元素 0、全等 0、两元素即唯一差。
两个高频追问:与基数排序的取舍、桶数为何只和 n 相关。
参考代码
from typing import Listclass Solution: def maximumGap(self, nums: List[int]) -> int: n = len(nums) if n < 2: return 0 lo, hi = min(nums), max(nums) if lo == hi: return 0 size = max(1, (hi - lo) // (n - 1)) cnt = (hi - lo) // size + 1 bmin = [10**20] * cnt bmax = [-(10**20)] * cnt used = [False] * cnt for x in nums: i = (x - lo) // size bmin[i] = min(bmin[i], x) bmax[i] = max(bmax[i], x) used[i] = True ans, prev = 0, lo for i in range(cnt): if not used[i]: continue ans = max(ans, bmin[i] - prev) prev = bmax[i] return ans复杂度
- 时间:O(n),求极值、入桶、扫桶各一遍线性
- 空间:O(n),桶数与 n 同量级,每桶存 min/max
易错点
面试追问把动画讲成自己的话
追问为什么不直接基数排序(radix sort)后扫一遍?
追问值域很大(如 10^9)会不会撑爆桶数组?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
最大数
LeetCode 179 · 中等 · 沿着 排序套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题