https://leetcode.com/problems/next-permutation
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
这题写起来不难代码量小,就是得仔细分析。这种算是FB爱的题型。
举个例子, 35421这种, 先从后往前找,1 2 4 5,这都是升序 (从后往前)。
对于从后往前都升序的序列你其实不能做什么, 因为它已经是最大的了,不可能更大了。
然后啪一下3出现了,降序。
如果把3和它后面的某个数对调,则可以搞一个更大的数。但是选哪个数呢。 肯定要选后面的数里面最接近3的数字。
就停在这里了,3就是我们想找的点,把3和 5421里面 比他大的最小值找出来,这里是4, 把4放在3的位置,这样就动用了最少的位数, 然后把5321排一下序,(其实不用排序, 因为这里面肯定是 降序,只要reverse一下就可以了)
如果从后往前一直是升序,直接reverse一下就好了。
class Solution {
public void nextPermutation(int[] nums) {
int N = nums.length;
// find the first(from right to left) bit that is smaller than its right friends
// call this bit number selectedNumber
int firstDecreasingBit = -1;
for (int i = N - 2; i >= 0; i--) {
if (nums[i] < nums[i + 1]) {
firstDecreasingBit = i;
break;
}
}
// using that bit, find the larger number than the selected Number.
if (firstDecreasingBit != -1) {
int nextLargerBit = firstDecreasingBit + 1;
for (int i = nextLargerBit + 1; i < N; i++) {
if (nums[i] > nums[firstDecreasingBit]) {
nextLargerBit = i;
} else break;
}
//swop the two number
swap(nums, firstDecreasingBit, nextLargerBit);
}
//sort the number after the firstDecreasing bit.
int l = firstDecreasingBit + 1, r = N - 1;
while (l < r) swap(nums, l++, r--);
return;
}
private void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
}