javascript实现 下一个排列| 8月更文挑战

226 阅读1分钟

上周的沸点活动-每日算法题里有一个这样的题目:下一个排列,要求是这样的:
实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。 必须 原地 修改,只允许使用额外常数空间。

思路
1、目的是返回下一个更大的排列,以1 2 3 4为例,依次排列是:

1 2 3 4   
1 2 4 3   
1 3 2 4   
1 3 4 2   
  .   
  .   
  .   
4 3 2 1

可以看出后一列一直大于前一列:1234 < 1243 < 1324 < 1342 < ... < 4321

2、我们从末尾开始一步一步向前排列,只要第一次找到nums[length] > nums[length - 1],就返回,然后nums[length]和nums[length - 1]交换,这时如果nums[length]就是最后一位数,没问题,结束了

3、但是如果nums[length]不是最后一位数,则还需要判断nums[length - 1]和nums[flag1 + 1]的大小,如果nums[flag1 + 1]大,这时候交换nums[flag1 - 1] 和nums[flag1 + 1]。

上代码

function nextLargerSpread(nums) {
      if (nums.lenght === 1) return nums;
      let before,
          after,
          next;
      let flag1 = nums.length - 1,
          flag2;
      for (let i = 0; i < nums.length; i++) {
        if (nums[flag1] > nums[flag1 -1 ]) {
          before = nums[flag1 - 1];
          after = nums[flag1];
          if (nums[flag1 - 1] < nums[flag1 + 1] && nums[flag1 + 1]) {
            flag2 = flag1 + 1;
            next = nums[flag1 + 1];
            nums[flag1 - 1] = next;
            nums[flag1 + 1] = before;
          } else {
            nums[flag1 - 1] = after;
            nums[flag1] = before
          }
          break;
        }
        flag1--;
        if (flag1 === 0) {
          nums = nums.reverse();
        }
      }
      if (flag2 < nums.length - 1 && nums[flag2 + 1]) {
        let start = (nums.slice(0, flag2 - 1));
        let endList = nums.slice(flag2 - 1).sort();
        nums = [...start, ...endList];
      }
    };

上一个imageslr大佬的图:

image.png 如果看不懂我的思路的话,可以点击下面链接看看大佬回答的图,我一开始看到这个题目也是一脸懵逼,然后就是看了大佬的图理解的。

图片来源:
leetcode-cn.com/problems/ne…