31. 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.
Examples1:
1,2,3 → 1,3,2
Examples2:
3,2,1 → 1,2,3
Examples3:
1,1,5 → 1,5,1
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/next-permutation
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
Think and method:
This question is not an easy question to understand. It may be easier to understand by looking directly at the example. In fact, it is simply a process of rearranging the sequence to find a larger sequence
**1. Violent **
This is the easiest and most straightforward way to think about it, we find every possible arrangement of the list made up of the elements of a given array, and we find a larger arrangement than the one given.
However, this method is too slow, requires too much searching and sorting process, takes a long time, and is too complicated in code implementation, beyond the time limit of the topic.
2. Only one scan is needed
Let’s focus on this.
- First, how do we find a larger sequence: find an ascending adjacent element and swap its large number with the decimal before the ascending order to achieve this, and we need to increase the minimum, so obviously we need to look from back to front
- After the swap, the ascending element is followed by descending, so we need to rearrange this to be in ascending order
- In special cases, if it cannot be found, the whole sequence can be sorted directly in descending order
we can use a more complex examples:
12374653
from right to left
first find ascending element 4 6
then find the element bigger than 4 is 5
swap 4 and 5
->12375643
and resort it
12375346
Time complexity: O(n)
Space complexity: O(1)
Codes:
func nextPermutation(nums []int) {
// Find the first ascending sequence from right to left
i := len(nums) - 2
for i >= 0 && nums[i] >= nums[i+1] {
i--
}
if i < 0 {
// the whole interval is dicreasing sequence and directly sort it
sort.Ints(nums)
}else {
j := len(nums)-1
// Find the first numeric index coordinate from right to left that is larger than the I index value
for j >= 0 {
if nums[j] > nums[i]{
nums[i], nums[j] = nums[j], nums[i]
break
}
j--
}
sort.Ints(nums[i+1:])
}
fmt.Println(nums)
}
Test:
Examples1:
1,2,3
Examples2:
3,2,1
Examples3:
1,1,5
Examples in the think and method
12374653
This question is more like a question that is inclined to the form of thinking. After careful consideration and reference, it seems that no other method has been found. From the perspective of utility, this is a question that needs to be practiced and tried, otherwise it is difficult to find a method on the spot.