Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
题目分析
给你一个整数数组 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 范围内的有效答案都将被判断为正确。
思路讲解
煎饼排序:每次只能反转数组中的第一个元素到第k个元素的子数组,然后我们每完成反转一次,就把k值记录下来。直到这个数组变成有序递增的,就输出我们记录的所有的k的值。
- 首先找到数组中的最大值,先将其反转至数组头部
- 在将其反转到该元素排序后的位置
- 然后找数组中的次大值,重复上述操作,直到数组排序完毕
示例
示例1
输入:[3,2,4,1]
输出:[4,2,4,3]
解释:
首先找到最大值4,记录下k=[3], 把4反转至数组头部,得到[4, 2, 3, 1], 然后把4放到后面得[2, 3, 1, 4], k=[3, 4]
找次大值为3,记录下来k=[3, 4, 2],把3反转至数组头部,得到[3, 2, 1, 4], 然后把3放到后面得[2, 1, 3, 4]
找次大值为2,把2反转至数组头部,得到[1,2,3,4], 记录下来k=[3, 4, 2, 3, 2]
示例2
输入: [1,2,3]
输出: []
解释: 输入已经排序,因此不需要翻转任何内容。
请注意,其他可能的答案,如 [3,3] ,也将被判断为正确。
代码
/*
* @lc app=leetcode.cn id=969 lang=javascript
*
* [969] 煎饼排序
*/
// @lc code=start
/**
* @param {number[]} arr
* @return {number[]}
*/
var pancakeSort = function(arr) {
// 1.找到数组中最大值的下标,然后反转前k个元素,把最大值放前面,然后把最大值放后面,然后在次大值,如此循环
// 2.反转数组,反转[0, arr.length-1]
let ans = [], max;
while (arr.length > 1) {
max = getMaxIndex(arr)
max > 0 && (ans.push(max + 1))
reverse(arr, max);
reverse(arr, arr.length - 1);
ans.push(arr.length);
arr.pop();
}
return ans;
};
// 1.找到最大数的下标
function getMaxIndex(arr) {
let max = 0;
for (let i = 0; i < arr.length; i++) {
if (arr[i] > arr[max]) {
max = i;
}
}
return max;
}
// 2.反转前k个元素, 反转数组从0到数组长度-1
var reverse = function (arr, k) {
if (k < 1) return
// i: 代表0, j:代表k
let i = 0, j = k;
while (i < j) {
[arr[i], arr[j]] = [arr[j], arr[i]];
i++;
j--;
}
}