煎饼排序
LeetCode 传送门969. Pancake Sorting
题目
给你一个整数数组 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 范围内的有效答案都将被判断为正确。
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 where 1 <= 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:
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.
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 from 1 to arr.length).
思考线
解题思路
这道题要求我们用煎饼翻转来完成数组的排序,如何找到能排序的规律是关键。假设len = arr.length
通过观察我发现
- 我们可以先找到最大的数的位置
i
,然后煎饼翻转k= i+1
,让最大的数放到最前面. - 接着我们煎饼翻转
len
,让最大的数放到最后面,然后len --
。 - 接着我们再找到
arr[0~-2]
中最大的数,执行操作1~2
即可,一直执行到i=2
为止。 - 对于煎饼翻转的过程:如果我们的翻转数为
k
,我们先定一个最小下标a=0
, 执行swap(arr[a],arr[k-1])
,进行数据交换,然后执行a ++,b --
即可。直到a>=b
为止,视为完成了煎饼翻转的过程。
整个代码的实现如下
/**
* @param {number[]} arr
* @return {number[]}
*/
var pancakeSort = function (arr) {
// 先找到最大的数的位置i, 然后煎饼翻转 i+1; 让最大的数放到最前面
// 接着煎饼翻转arr.length,让最大的数放到最后
// 接着在再找到arr[0~-2]中最大的,执行同样的操作即可。一直执行到 i = 1;
// 煎饼翻转的过程 假如从k开始翻转 那么每个i = k-1 -i;
// 代码实现如下
const res = [];
let max = 0;
for (let i = arr.length; i > 1; i--) { // 设置要煎饼翻转后最大值存放位置
for (let j = 0; j < i; j++) { // 遍历寻找 最大的值
if (arr[j] > arr[max]) {
max = j;
}
}
pancake(arr, max+1); // 把最大的值进行煎饼翻转
pancake(arr,i); // 把最大值存放到本次排序的最后位置
res.push(max+1) // 储存 煎饼排序的k值
res.push(i)
max = 0
}
return res;
};
function pancake(arr,b) {
let a = 0;
while(a < b-1) {
[arr[a], arr[b-1]] = [arr[b-1], arr[a]];
a++;
b--;
}
}
这就是我对本题的解法,如果有疑问或者更好的解答方式,欢迎留言互动。