题目描述
思路解析动画文字版
记牢这套「找最大,翻到顶,再翻到底」,下面每一轮都在套它。
这就是要排的一摞煎饼,数组 [3,2,4,1]。我们一轮一轮地把当前最大的那张归位,紫色框出的就是还没排好的前缀。
第 1 轮,未排前缀是 [下标 0 到 3]。先看下标 0 的 3,暂时当作最大。
看下标 1 的 2,比 3 小,最大还是 3。
看下标 2 的 4,比刚才的 3 大,最大刷新成 4。
看下标 3 的 1,比 4 小,最大还是 4。
这轮最大的饼是 4,它最终该躺在下标 3(前缀的最末位)。分两步翻过去。
第一翻:翻最上面 3 张(k=3),把 4 先翻到最顶。高亮的就是要翻的区间。
翻完前 3 张,4 现在到了最顶(下标 0)。
第二翻:翻最上面 4 张(k=4),把顶上的 4 一路翻到下标 3。
翻完前 4 张,4 归位在下标 3(蓝色),已排好的尾巴又长了一节。
第 2 轮,未排前缀是 [下标 0 到 2]。先看下标 0 的 1,暂时当作最大。
看下标 1 的 3,比刚才的 1 大,最大刷新成 3。
看下标 2 的 2,比 3 小,最大还是 3。
这轮最大的饼是 3,它最终该躺在下标 2(前缀的最末位)。分两步翻过去。
第一翻:翻最上面 2 张(k=2),把 3 先翻到最顶。高亮的就是要翻的区间。
翻完前 2 张,3 现在到了最顶(下标 0)。
第二翻:翻最上面 3 张(k=3),把顶上的 3 一路翻到下标 2。
翻完前 3 张,3 归位在下标 2(蓝色),已排好的尾巴又长了一节。
第 3 轮,未排前缀是 [下标 0 到 1]。先看下标 0 的 2,暂时当作最大。
看下标 1 的 1,比 2 小,最大还是 2。
这轮最大是 2,而且它已经在最顶(下标 0)了,第一次翻转可以省掉,直接做第二翻。
第二翻:翻最上面 2 张(k=2),把顶上的 2 一路翻到下标 1。
翻完前 2 张,2 归位在下标 1。最小的 1 也顺势落到下标 0,整摞全好了。
全部升序排好![1,2,3,4]。一路记录的翻转张数连起来就是答案:k 序列 3,4,2,3,2,一共 5 次翻转。
有序、两元素、单元素三种边界先想清,省得现场翻车。
两个高频追问:次数上界稳在限制内,但「最少次数」是另一个难题。
参考代码
from __future__ import annotationsfrom typing import *from collections import *from functools import *from itertools import *from math import *from heapq import *from bisect import *class Solution: def pancakeSort(self, arr: List[int]) -> List[int]: def reverse(arr, j): i = 0 while i < j: arr[i], arr[j] = arr[j], arr[i] i, j = i + 1, j - 1 n = len(arr) ans = [] for i in range(n - 1, 0, -1): j = i while j > 0 and arr[j] != i + 1: j -= 1 if j < i: if j > 0: ans.append(j + 1) reverse(arr, j) ans.append(i + 1) reverse(arr, i) return ans复杂度
- 时间:O(n²),共 n-1 轮,每轮扫一遍前缀找最大并翻转,都是 O(n)
- 空间:O(1),原地翻转,只用几个下标变量;答案数组不计入额外空间
- 翻转次数:≤ 2(n-1),每轮最多两翻,远在 10n 的限制内
易错点
面试追问把动画讲成自己的话
追问这套贪心的翻转次数上界是多少?会超题目限制吗?
追问能不能找到「最少翻转次数」的解?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
子串能表示从 1 到 N 数字的二进制串
LeetCode 1016 · 中等 · 沿着 双指针套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题