[路飞] 21——leetcode - [969] 煎饼排序

143 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

969. 煎饼排序

题目分析

给你一个整数数组 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--;
  }
}