【路飞】煎饼排序

181 阅读1分钟

题目:969. 煎饼排序

image.png

分析

话不多说,咱先上一个煎饼

image.png

对应的数组为[3,2,4,1],这时候客人觉得这个煎饼不太满意,他需要的煎饼是[1,2,3,4]这样的。这肯定是小意思,我们程序员都是很优秀的,写得了代码,煎得了饼😛
首先,我们考虑翻煎饼时是有一点限制的,我们每次只能将最上面的若干块烧饼翻转,如果我们要把4放到最底下,我们需要这样做:

  1. 先找到最大的元素4的位置,将3,2,4翻转,得到4,2,3,这样最大的4就翻转到了最上面;为了方便理解还画了一个铲子✌️ image.png
  2. 再将整个烧饼全部翻转,这样最大的4就翻到了最底下。

image.png

接着再将1,3,2按上面的方法再次排序,最终就能得到顾客想要的烧饼。

cakes.gif

解法一

利用递归实现,算法复杂度:O(n^2)

function pancakeSort(cakes) {
  let res = [];
  sort(cakes, cakes.length);
  function sort(cakes, n) {
    if (n == 1) return;
    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);
  }
  return res;
}

function reverse(arr, start, end) {
  while (start < end) {
    let temp = arr[start];
    arr[start] = arr[end];
    arr[end] = temp;
    start++;
    end--;
  }
}

解法二

双层循环,这个相比上面的那个容易理解一点

function pancakeSort(cakes) {
  let res = [];
  for (let i = cakes.length - 1; i >= 0; i--) {
    // 找到最大煎饼的位置
    let maxIndex = 0;
    for (let j = 0; j <= i; j++) {
      if (cakes[j] > cakes[maxIndex]) {
        maxIndex = j;
      }
    }
    // 将最大的煎饼翻转到第一个
    reverse(cakes, 0, maxIndex);
    // 记录翻转次数
    res.push(maxIndex + 1);
    // 反转数组,将最大的饼放在最后
    reverse(cakes, 0, i);
    // 记录翻转次数
    res.push(i + 1);
  }
  return res;
}

function reverse(arr, start, end) {
  while (start < end) {
    let temp = arr[start];
    arr[start] = arr[end];
    arr[end] = temp;
    start++;
    end--;
  }
}