[路飞]_每天刷leetcode_16(煎饼排序 Pancake Sorting)

604 阅读1分钟

煎饼排序

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通过观察我发现

  1. 我们可以先找到最大的数的位置i,然后煎饼翻转k= i+1,让最大的数放到最前面.
  2. 接着我们煎饼翻转len,让最大的数放到最后面,然后 len --
  3. 接着我们再找到 arr[0~-2]中最大的数,执行操作1~2即可,一直执行到i=2为止。
  4. 对于煎饼翻转的过程:如果我们的翻转数为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--;
    }
}

这就是我对本题的解法,如果有疑问或者更好的解答方式,欢迎留言互动。