题目:969. 煎饼排序
分析
话不多说,咱先上一个煎饼
对应的数组为[3,2,4,1],这时候客人觉得这个煎饼不太满意,他需要的煎饼是[1,2,3,4]这样的。这肯定是小意思,我们程序员都是很优秀的,写得了代码,煎得了饼😛
首先,我们考虑翻煎饼时是有一点限制的,我们每次只能将最上面的若干块烧饼翻转,如果我们要把4放到最底下,我们需要这样做:
- 先找到最大的元素4的位置,将3,2,4翻转,得到4,2,3,这样最大的4就翻转到了最上面;为了方便理解还画了一个铲子✌️
- 再将整个烧饼全部翻转,这样最大的4就翻到了最底下。
接着再将1,3,2按上面的方法再次排序,最终就能得到顾客想要的烧饼。
解法一
利用递归实现,算法复杂度:O(n^2)
function pancakeSort(cakes) {
let res = [];
sort(cakes, cakes.length);
function sort(cakes, n) {
if (n == 1) return;
let maxCake = 0;
let maxCakeIndex = 0;
for (let i = 0; i < n; i++) {
if (cakes[i] > maxCake) {
maxCakeIndex = i;
maxCake = cakes[i];
}
}
reverse(cakes, 0, maxCakeIndex);
res.push(maxCakeIndex + 1);
reverse(cakes, 0, n - 1);
res.push(n);
sort(cakes, n - 1);
}
return res;
}
function reverse(arr, start, end) {
while (start < end) {
let temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
解法二
双层循环,这个相比上面的那个容易理解一点
function pancakeSort(cakes) {
let res = [];
for (let i = cakes.length - 1; i >= 0; i--) {
// 找到最大煎饼的位置
let maxIndex = 0;
for (let j = 0; j <= i; j++) {
if (cakes[j] > cakes[maxIndex]) {
maxIndex = j;
}
}
// 将最大的煎饼翻转到第一个
reverse(cakes, 0, maxIndex);
// 记录翻转次数
res.push(maxIndex + 1);
// 反转数组,将最大的饼放在最后
reverse(cakes, 0, i);
// 记录翻转次数
res.push(i + 1);
}
return res;
}
function reverse(arr, start, end) {
while (start < end) {
let temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}