英文原文
Given an array of integers arr
, sort the array by performing a series of pancake flips.
In one pancake flip we do the following steps:
- Choose an integer
k
where1 <= k <= arr.length
. - Reverse the sub-array
arr[0...k-1]
(0-indexed).
For example, if arr = [3,2,1,4]
and we performed a pancake flip choosing k = 3
, we reverse the sub-array [3,2,1]
, so arr = [1,2,3,4]
after the pancake flip at k = 3
.
Return an array of the k
-values corresponding to a sequence of pancake flips that sort arr
. Any valid answer that sorts the array within 10 * arr.length
flips will be judged as correct.
Example 1:
Input: arr = [3,2,4,1] Output: [4,2,4,3] Explanation: We perform 4 pancake flips, with k values 4, 2, 4, and 3. Starting state: arr = [3, 2, 4, 1] After 1st flip (k = 4): arr = [1, 4, 2, 3] After 2nd flip (k = 2): arr = [4, 1, 2, 3] After 3rd flip (k = 4): arr = [3, 2, 1, 4] After 4th flip (k = 3): arr = [1, 2, 3, 4], which is sorted.
Example 2:
Input: arr = [1,2,3] Output: [] Explanation: The input is already sorted, so there is no need to flip anything. Note that other answers, such as [3, 3], would also be accepted.
Constraints:
1 <= arr.length <= 100
1 <= arr[i] <= arr.length
- All integers in
arr
are unique (i.e.arr
is a permutation of the integers from1
toarr.length
).
中文题目
给你一个整数数组 arr
,请使用 煎饼翻转 完成对数组的排序。
一次煎饼翻转的执行过程如下:
- 选择一个整数
k
,1 <= k <= arr.length
- 反转子数组
arr[0...k-1]
(下标从 0 开始)
例如,arr = [3,2,1,4]
,选择 k = 3
进行一次煎饼翻转,反转子数组 [3,2,1]
,得到 arr = [1,2,3,4]
。
以数组形式返回能使 arr
有序的煎饼翻转操作所对应的 k
值序列。任何将数组排序且翻转次数在 10 * arr.length
范围内的有效答案都将被判断为正确。
示例 1:
输入:[3,2,4,1] 输出:[4,2,4,3] 解释: 我们执行 4 次煎饼翻转,k 值分别为 4,2,4,和 3。 初始状态 arr = [3, 2, 4, 1] 第一次翻转后(k = 4):arr = [1, 4, 2, 3] 第二次翻转后(k = 2):arr = [4, 1, 2, 3] 第三次翻转后(k = 4):arr = [3, 2, 1, 4] 第四次翻转后(k = 3):arr = [1, 2, 3, 4],此时已完成排序。
示例 2:
输入:[1,2,3] 输出:[] 解释: 输入已经排序,因此不需要翻转任何内容。 请注意,其他可能的答案,如 [3,3] ,也将被判断为正确。
提示:
1 <= arr.length <= 100
1 <= arr[i] <= arr.length
arr
中的所有整数互不相同(即,arr
是从1
到arr.length
整数的一个排列)
通过代码
官方题解
方法:从大到小排序
思路
我们可以将最大的元素(在位置 i
,下标从 1 开始)进行煎饼翻转 i
操作将它移动到序列的最前面,然后再使用煎饼翻转 A.length
操作将它移动到序列的最后面。 此时,最大的元素已经移动到正确的位置上了,所以之后我们就不需要再使用 k
值大于等于 A.length
的煎饼翻转操作了。
我们可以重复这个过程直到序列被排好序为止。 每一步,我们只需要花费两次煎饼翻转操作。
算法
我们从数组 A 中的最大值向最小值依次进行枚举,每一次将枚举的元素放到正确的位置上。
每一步,对于在位置 i
的(从大到小枚举的)元素,我们会使用思路中提到的煎饼翻转组合操作将它移动到正确的位置上。 值得注意的是,执行一次煎饼翻转操作 f
,会将位置在 i, i <= f
的元素翻转到位置 f+1 - i
上。
class Solution {
public List<Integer> pancakeSort(int[] A) {
List<Integer> ans = new ArrayList();
int N = A.length;
Integer[] B = new Integer[N];
for (int i = 0; i < N; ++i)
B[i] = i+1;
Arrays.sort(B, (i, j) -> A[j-1] - A[i-1]);
for (int i: B) {
for (int f: ans)
if (i <= f)
i = f+1 - i;
ans.add(i);
ans.add(N--);
}
return ans;
}
}
class Solution(object):
def pancakeSort(self, A):
ans = []
N = len(A)
B = sorted(range(1, N+1), key = lambda i: -A[i-1])
for i in B:
for f in ans:
if i <= f:
i = f+1 - i
ans.extend([i, N])
N -= 1
return ans
复杂度分析
时间复杂度:$O(N^2)$,其中 $N$ 是数组
A
的长度。空间复杂度:$O(N)$。
统计信息
通过次数 | 提交次数 | AC比率 |
---|---|---|
16205 | 24975 | 64.9% |
提交历史
提交时间 | 提交结果 | 执行时间 | 内存消耗 | 语言 |
---|