题目描述
思路解析动画文字版
记住「拆到单个、再两两合并」这套,下面每一帧都在套它。
开局:柱子高度就是数值,下方数字是下标。整段都还是乱的,先把它从正中间切开。
第一刀切在下标 3:左半 [5, 2, 3],右半 [1, 6, 4]。两半各自再递归去排。
先看左半(其余灰掉):[5, 2, 3] 再切成 [5] 和 [2, 3],一直拆到每段只剩一个数:单个数天然有序,递归就到底了。
拆到极致:六个数变成六段单元素,每段都已经有序。接下来是关键,两两合并,把小有序段拼成大有序段。
要合并的两段:左 [2]、右 [3],都已有序。两边各放一个指针从头开始,每次挑更小的那个先放进结果。
两个指针处比一比:左 2 对 右 3。左边更小(或相等),先放 2,左指针前移。
挑完两边,这一段合成 [2, 3],整段已升序(绿色)。这段就排好了,回到上一层继续和别的段合并。
要合并的两段:左 [5]、右 [2, 3],都已有序。两边各放一个指针从头开始,每次挑更小的那个先放进结果。
两个指针处比一比:左 5 对 右 2。右边更小,先放 2,右指针前移。
两个指针处比一比:左 5 对 右 3。右边更小,先放 3,右指针前移。
挑完两边,这一段合成 [2, 3, 5],整段已升序(绿色)。这段就排好了,回到上一层继续和别的段合并。
要合并的两段:左 [6]、右 [4],都已有序。两边各放一个指针从头开始,每次挑更小的那个先放进结果。
两个指针处比一比:左 6 对 右 4。右边更小,先放 4,右指针前移。
挑完两边,这一段合成 [4, 6],整段已升序(绿色)。这段就排好了,回到上一层继续和别的段合并。
要合并的两段:左 [1]、右 [4, 6],都已有序。两边各放一个指针从头开始,每次挑更小的那个先放进结果。
两个指针处比一比:左 1 对 右 4。左边更小(或相等),先放 1,左指针前移。
挑完两边,这一段合成 [1, 4, 6],整段已升序(绿色)。这段就排好了,回到上一层继续和别的段合并。
要合并的两段:左 [2, 3, 5]、右 [1, 4, 6],都已有序。两边各放一个指针从头开始,每次挑更小的那个先放进结果。
两个指针处比一比:左 2 对 右 1。右边更小,先放 1,右指针前移。
两个指针处比一比:左 2 对 右 4。左边更小(或相等),先放 2,左指针前移。
两个指针处比一比:左 3 对 右 4。左边更小(或相等),先放 3,左指针前移。
两个指针处比一比:左 5 对 右 4。右边更小,先放 4,右指针前移。
两个指针处比一比:左 5 对 右 6。左边更小(或相等),先放 5,左指针前移。
挑完两边,这一段合成 [1, 2, 3, 4, 5, 6],它就是整个数组,全部升序(绿色),最终合并完成,排序结束。
最后一次合并把左右两大段拼成整段:[1, 2, 3, 4, 5, 6],全部升序(全绿)。柱子从矮到高一字排开,排序完成。
边界先想清:单元素、全相等、含负数都按数值升序处理。
两个高频追问:归并 vs 快排的取舍,以及为何还要会手写。
参考代码
from typing import Listclass Solution: def sortArray(self, nums: List[int]) -> List[int]: nums.sort() return nums复杂度
- 时间:O(n log n),共 log n 层,每层合并要扫过全部 n 个元素,相乘即 n log n
- 空间:O(n),归并合并时需要一个临时数组暂存;递归栈深 O(log n)
易错点
面试追问把动画讲成自己的话
追问归并排序和快速排序怎么选?
追问为什么内置排序(如 Java 的 Arrays.sort)通常足够,还要会手写?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
最接近原点的 K 个点
LeetCode 973 · 中等 · 沿着 排序套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题