问题:969. 煎饼排序
给定数组 A
,我们可以对其进行煎饼翻转:我们选择一些正整数 k <= A.length
,然后反转 A
的前 k 个元素的顺序。我们要执行零次或多次煎饼翻转(按顺序一次接一次地进行)以完成对数组 A
的排序。
返回能使 A
排序的煎饼翻转操作所对应的 k 值序列。任何将数组排序且翻转次数在 10 * A.length
范围内的有效答案都将被判断为正确。
示例 1:
输入:[3,2,4,1] 输出:[4,2,4,3] 解释: 我们执行 4 次煎饼翻转,k 值分别为 4,2,4,和 3。 初始状态 A = [3, 2, 4, 1] 第一次翻转后 (k=4): A = [1, 4, 2, 3] 第二次翻转后 (k=2): A = [4, 1, 2, 3] 第三次翻转后 (k=4): A = [3, 2, 1, 4] 第四次翻转后 (k=3): A = [1, 2, 3, 4],此时已完成排序。
示例 2:
输入:[1,2,3] 输出:[] 解释: 输入已经排序,因此不需要翻转任何内容。 请注意,其他可能的答案,如[3,3],也将被接受。
提示:
1 <= A.length <= 100
A[i]
是[1, 2, ..., A.length]
的排列
链接:https://leetcode-cn.com/contest/weekly-contest-118/problems/pancake-sorting/
分析:
翻转次数在10*A.length的都被判为正确,那么可以采用如下策略:
对于某个数组A0 A1...An,假设最大值为Ai
第一次翻转前i+1个,将Ai翻转到首位,然后翻转n+1个,将Ai翻转到最后,接下来处理A0 A1 ...Ai-1 Ai+1...An,这样的话每个数字经过两次翻转转到目标位置,满足小于10*要求。
则需要:
1.剩余待处理长度L。
2.剩余数字中最大值位置N。
3.翻转前N个。
4.翻转前L个。
AC Code:
class Solution { public: vector<int> pancakeSort(vector<int>& A) { vector<int> ret; int right = A.size(); while(IsSorted(A) != true) { //找到当期最大值位置 int max = FindMaxlocation(A, right); if (max == right) { right--; } else { //先将最大值翻转到第一个,然后翻转到最后一个 ret.emplace_back(max); A = Swap(A, max); ret.emplace_back(right); A = Swap(A, right); right--; } } return ret; } vector<int> Swap(vector<int> vec, int n) { n = n - 1; vector<int> ret; for (int i = 0; i < vec.size(); i++) { if (i <= n) { ret.emplace_back(vec[n-i]); } else { ret.emplace_back(vec[i]); } } return ret; } int FindMaxlocation(vector<int> vec, int lim) { int ret = 0; for (int i = 1; i < lim; i++) { if (vec[i] > vec[ret]) { ret = i; } } ret += 1; return ret; } };
其他:
第一code:
class Solution(object): def pancakeSort(self, A): """ :type A: List[int] :rtype: List[int] """ if len(A) == 1: return [] mmax = len(A) index = A.index(mmax) A[:index+1] = reversed(A[:index+1]) A.reverse() return [index+1, len(A)] + self.pancakeSort(A[:-1])
利用python的截取功能递归处理,基本思路一样。