[路飞]_煎饼排序

427 阅读1分钟

题目介绍

给你一个整数数组 arr ,请使用 煎饼翻转 完成对数组的排序。

一次煎饼翻转的执行过程如下:

  • 选择一个整数 k1 <= 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 范围内的有效答案都将被判断为正确。

示例1

输入:[3,2,4,1]
输出:[4,2,4,3]
解释:
我们执行 4 次煎饼翻转,k 值分别为 424,和 3。
初始状态 arr = [3, 2, 4, 1]
第一次翻转后(k = 4):arr = [1, 4, 2, 3]
第二次翻转后(k = 2):arr = [4, 1, 2, 3]
第三次翻转后(k = 4):arr = [3, 2, 1, 4]
第四次翻转后(k = 3):arr = [1, 2, 3, 4],此时已完成排序。

示例2

输入: [1,2,3]
输出: []
解释: 输入已经排序,因此不需要翻转任何内容。
请注意,其他可能的答案,如 [33] ,也将被判断为正确。
提示:
  • 1 <= arr.length <= 100
  • 1 <= arr[i] <= arr.length
  • arr 中的所有整数互不相同(即,arr 是从 1arr.length 整数的一个排列) leetcode-969 煎饼排序
    b站视频

解题思路

想办法把最大的值反转到数组末尾,然后将其从数组中移除,继续对次大值进行此操作
(为什么不把最小值移到第一位,因为每次都是前 n 个数进行翻转,第一位总是会被翻转,而把最大值移到最后一位之后,我们就可以不移动最后一位了)

解题步骤

1.找到数组中最大值的下标
2.如果最大值在第一位,跳到步骤3,如果最大值在最后一位,跳到步骤4,否则,将最大值之前的数进行翻转,此时最大值会被翻转到第一位
3.把整个数组进行翻转,此时最大值会被翻转到最后一位
4.将最后一位从数组中移除
5.重复 1-4,直到数组的长度为 0

1.gif

解题代码

 var pancakeSort = function(arr) {
    const ret = []
    while (arr.length) {
        let max = getMax(arr)
        // 如果最大值在最后一位,直接将其从数组中移除
        if (max !== arr.length - 1) {
            // 如果最大值在第一位,直接翻转整个数组
            if (max !== 0) {
                ret.push(max + 1)
                reverse(arr, max)
            }
            ret.push(arr.length)
            reverse(arr, arr.length - 1)
        }
        arr.pop()
    }
    return ret
};

var getMax = function (arr) {
    let s = 0
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] > arr[s]) s = i
    }
    return s
}

var reverse = function (arr, k) {
    let i = 0
    while (i < k) {
        [arr[i], arr[k]] = [arr[k], arr[i]]
        i++
        k--
    }
}

以上就是本题的解题思路,欢迎查看我的其他文章
[路飞]_环形链表
[路飞]_环形链表II
[路飞]_快乐数
[路飞]_反转链表
[路飞]_反转链表II
[路飞]_K 个一组翻转链表
[路飞]_旋转链表
[路飞]_两两交换链表中的节点
[路飞]_最近的请求次数
[路飞]_第 k 个数
[路飞]_亲密字符串
[路飞]_柠檬水找零