煎饼排序(Pancake Sorting)
字数 1135 2025-10-27 22:14:39

煎饼排序(Pancake Sorting)

题目描述
给定一个整数数组 arr,你需要通过一系列“煎饼翻转”操作将数组排序。一次煎饼翻转的操作步骤如下:

  1. 选择一个整数 k1 ≤ k ≤ arr.length)。
  2. 反转子数组 arr[0...k-1](即下标从 0 到 k-1 的元素)。

最终数组需按升序排列。请设计算法,返回一系列翻转操作对应的 k 值序列。


解题思路
煎饼排序的核心思想是每次将当前未排序部分的最大值翻到最前,再翻到未排序部分的末尾,通过两次翻转完成一个元素的归位。具体步骤如下:

  1. 从后往前确定位置

    • n 为数组长度,当前需确定 arr[n-1] 的值,然后 arr[n-2],依此类推。
    • 对于每个位置 i(从 n-11),找到未排序部分(arr[0...i])中的最大值及其索引 maxIndex
  2. 第一次翻转

    • 若最大值不在当前未排序部分的首位(即 maxIndex != 0),则将 arr[0...maxIndex] 翻转,使最大值翻到最前面。记录此次翻转的 k 值为 maxIndex + 1
  3. 第二次翻转

    • 将整个未排序部分 arr[0...i] 翻转,使最大值翻到当前未排序部分的末尾(即位置 i)。记录此次翻转的 k 值为 i + 1
  4. 重复步骤 1~3,直到所有元素归位。


示例演示
arr = [3, 2, 4, 1] 为例:

  1. 当前未排序部分[3, 2, 4, 1](i=3)

    • 最大值 4 的索引 maxIndex = 2
    • 第一次翻转(k=3):[4, 2, 3, 1](将 4 翻到最前)。
    • 第二次翻转(k=4):[1, 3, 2, 4](将 4 翻到末尾)。
  2. 当前未排序部分[1, 3, 2](i=2)

    • 最大值 3 的索引 maxIndex = 1
    • 第一次翻转(k=2):[3, 1, 2, 4](将 3 翻到最前)。
    • 第二次翻转(k=3):[2, 1, 3, 4](将 3 翻到末尾)。
  3. 当前未排序部分[2, 1](i=1)

    • 最大值 2 的索引 maxIndex = 0(无需第一次翻转)。
    • 第二次翻转(k=2):[1, 2, 3, 4](将 2 翻到末尾)。

翻转序列:k = [3, 4, 2, 3, 2]


关键点说明

  • 每次操作将最大值归位需最多两次翻转。
  • 若最大值已在末尾,则跳过本次操作。
  • 时间复杂度为 O(n²),但重点在于翻转次数尽可能少(本题不要求最优翻转次数)。

通过这种模拟方法,可以逐步将数组排序,同时记录每次翻转的 k 值。

煎饼排序(Pancake Sorting) 题目描述 给定一个整数数组 arr ,你需要通过一系列“煎饼翻转”操作将数组排序。一次煎饼翻转的操作步骤如下: 选择一个整数 k ( 1 ≤ k ≤ arr.length )。 反转子数组 arr[0...k-1] (即下标从 0 到 k-1 的元素)。 最终数组需按升序排列。请设计算法,返回一系列翻转操作对应的 k 值序列。 解题思路 煎饼排序的核心思想是 每次将当前未排序部分的最大值翻到最前,再翻到未排序部分的末尾 ,通过两次翻转完成一个元素的归位。具体步骤如下: 从后往前确定位置 : 设 n 为数组长度,当前需确定 arr[n-1] 的值,然后 arr[n-2] ,依此类推。 对于每个位置 i (从 n-1 到 1 ),找到未排序部分( arr[0...i] )中的最大值及其索引 maxIndex 。 第一次翻转 : 若最大值不在当前未排序部分的首位(即 maxIndex != 0 ),则将 arr[0...maxIndex] 翻转,使最大值翻到最前面。记录此次翻转的 k 值为 maxIndex + 1 。 第二次翻转 : 将整个未排序部分 arr[0...i] 翻转,使最大值翻到当前未排序部分的末尾(即位置 i )。记录此次翻转的 k 值为 i + 1 。 重复步骤 1~3 ,直到所有元素归位。 示例演示 以 arr = [3, 2, 4, 1] 为例: 当前未排序部分 : [3, 2, 4, 1] (i=3) 最大值 4 的索引 maxIndex = 2 。 第一次翻转(k=3): [4, 2, 3, 1] (将 4 翻到最前)。 第二次翻转(k=4): [1, 3, 2, 4] (将 4 翻到末尾)。 当前未排序部分 : [1, 3, 2] (i=2) 最大值 3 的索引 maxIndex = 1 。 第一次翻转(k=2): [3, 1, 2, 4] (将 3 翻到最前)。 第二次翻转(k=3): [2, 1, 3, 4] (将 3 翻到末尾)。 当前未排序部分 : [2, 1] (i=1) 最大值 2 的索引 maxIndex = 0 (无需第一次翻转)。 第二次翻转(k=2): [1, 2, 3, 4] (将 2 翻到末尾)。 翻转序列 :k = [ 3, 4, 2, 3, 2 ] 关键点说明 每次操作将最大值归位需最多两次翻转。 若最大值已在末尾,则跳过本次操作。 时间复杂度为 O(n²),但重点在于翻转次数尽可能少(本题不要求最优翻转次数)。 通过这种模拟方法,可以逐步将数组排序,同时记录每次翻转的 k 值。