题目描述
找出这个数组排序出的所有数中,刚好比当前数大的那个数
比如当前 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);
}