Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.
If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).
The replacement must be in-place and use only constant extra memory.
Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
1,2,3
→ 1,3,2
3,2,1
→ 1,2,3
1,1,5
→ 1,5,1
找到下一个大的组合。
这里直接给出LeetCode上的解法,据说是14世纪的算法...
具体写起来的话很简单:
需要仔细理解下面的注释
// Find the largest index k such that nums[k] < nums[k + 1] If no such index exists, just reverse nums and done
//nums[0:k-1]是nums和next permutation的公共部分
// Find the largest index l > k such that nums[k] < nums[l]
// Swap nums[k] and nums[l]
//现在nums[0:k-1]后面是nums[l],而nums[0:k-1]串上nums[l]就是next permutation的开头部分
// Reverse the sub-array nums[k + 1:] 剩下的这部分逆序之后就走向了nums[0:k-1]串nums[l]的子树的最左分支(最小分支)
public void nextPermutation(int[] nums) {
int n = nums.length;
int k;
int l;
for(k = n - 2; k >= 0; k--) {
if(nums[k] < nums[k + 1]) {
break;
}
}
if(k < 0){//不存在使得nums[k]>nums[k+1]的k
reverseFrom(nums,0);
}
else{
for(l = n - 1; l > k; l--) {
if(nums[l] > nums[k]) {
break;
}
}
//能找到k的话, l一定存在
swap(nums,k,l);
reverseFrom(nums,k + 1);
}
}
private void reverseFrom(int[] nums,int start){
int i = start;
int j = nums.length-1;
while(i<j){
swap(nums,i,j);
i++;
j--;
}
return;
}
private void swap(int[] nums,int i,int j){
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
return;
}
看下面这个例子,1243的next permutation是1324
第一步,k=1
第二步, l=3
第三步,交换nums[k]和nums[l],nums变为1342
第四步,k+1=2,将nums[2:]逆序,得到nums为1324