实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
字典序是什么
字典序(dictionary order),又称 字母序(alphabetical order),原意是表示英文单词在字典中的先后顺序,在计算机领域中扩展成两个任意字符串的大小关系。
英文中的 字母表(Alphabet) 按照如下的顺序排列:
ABCDEFG HIJKLMN OPQRST UVWXYZ
abcdefg hijklmn opqrst uvwxyz
在字典中,单词是按照首字母在字母表中的顺序进行排列的
在计算机领域中,这个字典序就不仅仅用来比较英文单词了,而是比较任意字符串。对于两个字符串,大小关系取决于两个字符串从左到右第一个不同字符的 ASCII 值的大小关系。
字典序算法如下:
1.如果当前排列为124653,要找到它的下一个排列,就要从右往左找到它的第一个左小于右的数
2.如果找不到,则说明排列求解完成。如果找得到说明排列未完成
3.本例中左小于右的数为46,把4所在的位置记为i,然后再从右到左找到第一个第一个比4大的数,本例为5,把5所在的位置记为j
4.将i和j所对应的元素互换,即4和5交换,排列变为125643
5.然后将i+1到最后一个元素进行从小到大的排列,本例得125346
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>力扣31</title>
</head>
<body>
<script>
var nextPermutation = function(nums){
let len = nums.length;
if(len <= 1) return;
for(let i = len - 2;i>=0;i--)//i指向倒数第二个元素,控制左值
{
if(nums[i]<nums[i+1]){
//倒着遍历,找出第一个左值大于右值
for(let j = len - 1;j>i;j--){
//j指向最后一个元素,找出比左值i大的第一个元素
if(nums[j]>nums[i]){
swap(i,j,nums);//找到了之后进行叫唤
break;
}
}
let x = i+1,y = len - 1;
while(x<y) swap(x++,y--,nums);
break;
}
if(i==0){
let x = i,y = len - 1;
while(x<y) swap(x++,y--,nums)
}
}
};
function swap(i,j,nums){
let t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
</script>
</body>
</html>