题目描述
思路解析动画文字版
为什么?排好序后下标 i 上应该是数字 i。如果前 i+1 个数的最大值恰好是 i,说明 0..i 这些数字正好填满了 0..i 这些位置,左边自成一块、和右边再不纠缠,所以能切。
准备 · arr = [1,0,2,3,4]:我们让一个指针从左往右扫,一路维护「到目前为止见过的最大值」maxv。每到一格,先更新 maxv,再看 maxv 是否等于当前下标。
i=0 · 更新 maxv:指针落在下标 0,值是 1。更新前缀最大值:maxv = 1。
i=0 · maxv=1 ≠ 0 · 不能切:maxv(1) ≠ i(0)。出现了比 0 大的数,说明数字 0 还在后面没遇到,这一块没法封口,不能切。
i=1 · 更新 maxv:指针挪到下标 1,值是 0。maxv 取较大者还是 1(没变大)。
i=1 · maxv=1 == 1 · 切!:maxv(1) == i(1)!前两格里的数 {0,1} 正好填满位置 {0,1},左边 [1,0] 自成一块。切一刀,块数 = 1。
i=2 · 更新 maxv:指针到下标 2,值是 2。maxv 被刷新成 2。
i=2 · maxv=2 == 2 · 切!:maxv(2) == i(2)!到这里 0..2 的数正好填满 0..2 的位置,[2] 单独成块。块数 = 2。
i=3 · 更新 maxv:指针到下标 3,值是 3。maxv 刷新成 3。
i=3 · maxv=3 == 3 · 切!:maxv(3) == i(3)![3] 又是独立一块。块数 = 3。
i=4 · 更新 maxv:指针到最后一格下标 4,值是 4。maxv 刷新成 4。
i=4 · maxv=4 == 4 · 切!完成:maxv(4) == i(4)!最后一刀,[4] 独立成块。扫完一遍,总共切出 4 块,这就是答案。
结果 · 4 块:每个「maxv == i」的位置都是一个切口。整趟一次遍历、一个变量,O(n) 就数完了块数。
下面用倒序数组走一遍,体会「前面只要冒出一个大数,后面就被它牢牢绑住切不开」。
反例 · arr = [4,3,2,1,0]:换成完全倒序的 [4,3,2,1,0],规则不变,看 maxv 怎么一路被 4 卡住。
i=0 · 更新 maxv:指针落在下标 0,第一格就是最大值 4,maxv 直接被顶到 4。
i=0 · maxv=4 ≠ 0 · 不切:maxv(4) ≠ i(0)。这个 4 要等到下标 4 才安顿好,在那之前哪也切不了。
i=1 · maxv=4 ≠ 1:下标 1,值 3,比 4 小,maxv 不变,仍是 4。4 ≠ 1,切不开。
i=2 · maxv=4 ≠ 2:下标 2,值 2,maxv 还是 4。4 ≠ 2,继续不能切。
i=3 · maxv=4 ≠ 3:下标 3,值 1,maxv 仍 4。4 ≠ 3,还差一步。
i=4 · maxv=4 == 4 · 只切这一刀:直到最后一格 i=4,maxv 才等于下标。整个数组只能算 1 块——前面的大数把后面全锁死了,这正是贪心判据的威力。
雷区实演 · 看相邻会切错:假如只盯相邻两格的大小关系,就解释不清「为什么 i=0 不能切、i=1 能切」。真正的依据是前缀最大值 maxv 何时追上下标,这是全局信息,相邻比较替代不了。
边界三连:想清楚「全升序切满 n 块」「全倒序只切 1 块」「最小乱序切 1 块」三种极端,代码就稳了。
面试追问:把「贪心为何对」和「推广到 LC768」讲清楚,是这题面试的高分点。
参考代码
class Solution: def maxChunksToSorted(self, arr): max_so_far = 0 chunks = 0 for i in range(len(arr)): if arr[i] > max_so_far: max_so_far = arr[i] if max_so_far == i: # 前缀最大值追平下标 → 切 chunks += 1 return chunks复杂度
- 时间复杂度:O(n),只从左到右扫一遍数组,每格做一次取最大值和一次相等判断,共 n 次 → O(n)
- 空间复杂度:O(1),只用了 max_so_far 和 chunks 两个变量,不随数组规模增长 → O(1)
易错点
面试追问把动画讲成自己的话
追问为什么贪心(前缀最大值==下标)一定对?
追问如果数组不是排列,而是任意可重复整数(LC768)怎么办?
追问为什么是 O(n) 而不能更快?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
一手顺子
LeetCode 846 · 中等 · 沿着 贪心套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题