每日一道算法Day15

235 阅读1分钟

题目描述

找出这个数组排序出的所有数中,刚好比当前数大的那个数

比如当前 nums = [1,2,3]。这个数是123,找出1,2,3这3个数字排序可能的所有数,排序后,比123大的那个数 也就是132

如果当前 nums = [3,2,1]。这就是1,2,3所有排序中最大的那个数,那么就返回1,2,3排序后所有数中最小的那个,也就是1,2,3 -> [1,2,3]

大致思路

倒叙循环数组, 比较邻近的两个值(即nums[i]与nums[i-1]), 如果 nums[i] > nums[i-1], 及代表可以找出大于当前的那个数。然后取出nums[i] ===> nums[nums.length - 1]这一段中的最小值, 与nums[i - 1]比较。如果min > nums[i-1], 这交换这两个值的位置, 否则交换nums[i] 与nums[i - 1]的值。 最后对nums[i] ===> nums[nums.length - 1]这一段进行升序排序, 取到刚好大于之前的那个数的值。

代码如下:

function nextPermutation(nums: number[]): void {
 //用来标记是否可以找到刚好大于当前数的那个值
  let flag = true;
  for (let i = nums.length - 1; i > 0; --i) {
    if (nums[i - 1] < nums[i] && flag) {
      flag = false;
      //取到到最小值
      let min = Math.min(...nums.slice(i, nums.length).filter((item) => item > nums[i - 1]));
      if (nums[i - 1] < min) {
        let minIndexOf = nums.slice(i, nums.length).indexOf(min) + i;
        let tmp = nums[i - 1];
        nums[i - 1] = nums[minIndexOf];
        nums[minIndexOf] = tmp;
      } else {
        let tmp = nums[i - 1];
        nums[i - 1] = nums[i];
        nums[i] = tmp;
      }
      //对nums[i] ===> nums[nums.length - 1]这一段进行升序排
      for (let j = 0; j < nums.length - i - 1; j++) {
        for (let k = i; k < nums.length - j - 1; k++) {
          if (nums[k] > nums[k + 1]) {
            let tmp = nums[k];
            nums[k] = nums[k + 1];
            nums[k + 1] = tmp;
          }
        }
      }
    }
  }
  //没有找到, 直接进行降序排序。
  if (flag) nums.sort((a, b) => a - b);
}