31. Next Permutation
Problem description:
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
31,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
Solution:
index: 0,1,2,3,4,5
value: 2,3,6,5,4,1
1. from right to left, find the first number which not increase in a ascending order. In this case which is 3.
2. here we can have two situations:
We cannot find the number, all the numbers increasing in a ascending order. This means this permutation is the last permutation, we need to rotate back to the first permutation. So we reverse the whole array, for example,
6,5,4,3,2,1
we turn it to1,2,3,4,5,6
.We can find the number, then the next step, we will start from right most to leftward, try to find the first number which is larger than 3, in this case it is 4.
Then we swap 3 and 4, the list turn to2,4,6,5,3,1
.
Last, we reverse numbers on the right of 4, we finally get2,4,1,3,5,6
.
Time complexity: O(3*n)=O(n).
1 | class Solution: |
1 | class Solution { |
Another solution:
Just for info: There’s a library function that does the job, even going from totally reverse sorted to sorted:1
2
3void nextPermutation(vector<int>& nums) {
next_permutation(begin(nums), end(nums));
}
Another Solution
Using library functions for all building blocks of the algorithm. Very nice how they all play together, notice the total lack of +1/-1, it all fits exactly.1
2
3
4
5
6void nextPermutation(vector<int>& nums) {
auto i = is_sorted_until(nums.rbegin(), nums.rend());
if (i != nums.rend())
swap(*i, *upper_bound(nums.rbegin(), i, *i));
reverse(nums.rbegin(), i);
}
Second Time:
The last reverse
is because, we need to reverse the order after we swap a smaller element to the back.
For example:1
2
3
4
5
6
7
8
9[1,3,2], left= 0, right= 2
after swap
[2,3,1]
we can see that the next permutation should be [2,1,3], which should start with the nums[right] we just swap to the back
Therefore, we need to reverse the order so it could be in the front and make a
[2,1,3]
1 | class Solution { |