Given an array A
, we can perform a pancake flip: We choose some positive integer k <= A.length
, then reverse the order of the first k elements of A
. We want to perform zero or more pancake flips (doing them one after another in succession) to sort the array A
.
Return the k-values corresponding to a sequence of pancake flips that sort A
. Any valid answer that sorts the array within 10 * A.length
flips will be judged as correct.
Example 1:
Input: [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: A = [3, 2, 4, 1] After 1st flip (k=4): A = [1, 4, 2, 3] After 2nd flip (k=2): A = [4, 1, 2, 3] After 3rd flip (k=4): A = [3, 2, 1, 4] After 4th flip (k=3): A = [1, 2, 3, 4], which is sorted.
Example 2:
Input: [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.
这次涉及的是煎饼排序,这是一个以前听都没听过的算法;
算法主题操作就是反转数组,问题的核心关键是反转几次数组;
对于一个元素来说,如果想让其出现在队尾,则必须要先反转到头部,再次反转到尾部。
如果采用未优化的普适算法,而不是纠结于比尔盖茨所研究的最优算法的话,整体思路如下:
对于n个元素,我们最坏要进行n次反转,每次反转的目的是将第i大的元素反转到队尾;
所以:
1.寻找1~i中最大的元素,假设为第m。
2.反转1~m,使得最大的元素到队头。
3.反转1~i,使得最大的元素到队尾。
重复上述步骤n次,并且i从n开始取到1;
此时,就会使第n大、第n-1大到最后第一个元素经过两次反转换到相应的位置上;
整体代码如下所示:
class Solution {
public:
vector pancakeSort(vector& A) {
vectorres;
for(int i=0;iA[max])
max=j;
reverse(A.begin(),A.begin()+max+1);
res.push_back(max+1);
reverse(A.begin(),A.begin()+A.size()-i);
res.push_back(A.size()-i);
for(int k=0;k
如果直接采用寻找第n大的数(也就是当前1~i最大的数)进行循环判定,则代码如下,主体部分相同:
class Solution {
public:
vector pancakeSort(vector A) {
vector res;
int x,i;
for (x = A.size(); x > 0; --x) {
for (i = 0; A[i] != x; ++i);
reverse(A.begin(), A.begin() + i + 1);
res.push_back(i + 1);
reverse(A.begin(), A.begin() + x);
res.push_back(x);
}
return res;
}
};