第三十四天:力扣第31题,下一个排列
思路:先找第一个比左边n大的数字m,再找右边的最小大于n的数,对后面的数再进行排序
var nextPermutation = function(nums) {
let flag = 0;
let res = 0;
for(let i = nums.length - 1; i > 0; i--)
{
if(nums[i] > nums[i - 1]){
res = i;
flag = 1;
for(let j = i + 1; j < nums.length; j++)
{
if(nums[j] <= nums[res] && nums[j] > nums[i - 1])
{
res = j;
}
}
[nums[res],nums[i - 1]] = [nums[i - 1],nums[res]];
if(res - i > 0)
{
var a = nums.slice(-(nums.length - i)).sort((a,b) => a-b);
nums.splice(i,nums.length - i);
nums.push(a);
}
break;
}
}
return flag == 1 ? nums : nums.sort((a,b) => a - b)
};
代码在idea上可以跑起来,在力扣上是NaN,就很烦
再贴一下大佬的代码,思路其实差不多
function nextPermutation(nums) {
let i = nums.length - 2; // 从倒数第二个,向左遍历
while (i >= 0 && nums[i] >= nums[i + 1]) { // 寻找第一个小于右邻居的数
i--;
}
if (i >= 0) { // 这个数在数组中存在
let j = nums.length - 1; // 从最后一项,向左遍历
while (j >= 0 && nums[j] <= nums[i]) { // 寻找第一个小于 nums[i] 的数
j--;
}
[nums[i], nums[j]] = [nums[j], nums[i]]; // 两数交换,实现变大
}
// 如果i=-1,说明是递减排列,如 321,则直接翻转为最小排列:123
let l = i + 1; // i 右边的数进行翻转,使得变大的幅度小一些
let r = nums.length - 1;
while (l < r) {
[nums[l], nums[r]] = [nums[r], nums[l]];
l++;
r--;
}
}