算法_煎饼排序(#969)

126 阅读2分钟

题目

给一个整数数组arr,使用煎饼翻转完成对数组的排序,
以数组的形式返回能使arr有序的煎饼翻转操作所对应的k值序列,任何将数组排序且翻转次数在10*arr.length范围捏的有效答案都将被判断为正确 就是通过翻转n次,翻转成有序队列

image.png

分析一波

思路

每次把数组中最大的数放到最后; 这样做:两次翻转把最大数放在最后,第一次是找数组里最大的数,然后从这个最大数的位置截止,到之前的数字小翻转一次,目的是把这个最大数放到头部;
然后再进行第二次大的翻转,目的是把最大数放到尾部;
剩下的数字里再次找最大的数,以此类推,翻转两次,直到把当前最大的数放到当前几个数字的末尾; 直到所有的数字进行完以上操作,就会形成一个排序的数组; 比如3,2,4,1先找到最大的数4,然后从最大的这个数的位置截止全部翻转的开头,成了4,2,3,1;
然后再整体翻转一次,成1,3,2,4,这样就把最大数放最后啦;
然后除过上次那个4之后,再次找剩余里面最大的数是3,然后从3这里开始第一次翻转,把3翻转到开头是3,1,2,4;
再第二次翻转:把最大数3翻转到3,1,2这几个数字的最后,是2,1,3,4;

代码

var pancakeSort = function(arr) {
  //翻转函数
  const reverse = (arr, i, j) => {
    while (i < j){
      const temp = arr[i];
      arr[i] = arr[j];
      arr[j] = temp;
      i++;
      j--;
    }
  }
  //排序
  const sort = (cakes, n) => {
    //base case
    if (n == 1) {
      return;
    }
    //寻找最大的index
    let maxCake = 0;
    let maxCakeIndex = 0;
    for (let i = 0; i < n; i++){
      if (cakes[i] > maxCake){
        maxCakeIndex = i;
        maxCake = cakes[i];
      } 
    }
    //第一次翻转,最大数在最头部
      reverse(cakes, 0, maxCakeIndex);
      res.push(maxCakeIndex + 1);
      //第二次翻转,最大数到尾部
      reverse(cakes, 0, n - 1);
      res.push(n);
      //递归
      sort(cakes, n - 1);
  }
  const res = [];
  sort(arr, arr.length);
  return res

先写了个reverse翻转函数,去翻转对应的数组;
找出最大数的下标;
然后利用reverse翻转函数进行第一次翻转,把最大数翻转到头部;
然后再进行第二次翻转,把最大数翻转到尾部,依次循环,类推,直到全部的数已经翻转完毕;
得到一个升序的数组;