|
| 1 | +""" |
| 2 | +31. Next Permutation |
| 3 | +
|
| 4 | +https://leetcode.com/problems/next-permutation |
| 5 | +
|
| 6 | +NOTES |
| 7 | + * Use a special algorithm. You just need to know how to do this one. |
| 8 | +
|
| 9 | +Definitions |
| 10 | +----------- |
| 11 | +A permutation of an array of integers is an arrangement of its members into a |
| 12 | +sequence or linear order. |
| 13 | +
|
| 14 | +For example, all permutations of the array [1, 2, 3] are: |
| 15 | +
|
| 16 | + [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1] |
| 17 | +
|
| 18 | +The next permutation of an array of integers is the next lexicographically |
| 19 | +greater permutation of its integers. If the arrangement for the next possible |
| 20 | +permutation does not exist, the next permutation is the first (lowest) |
| 21 | +permutation. |
| 22 | +
|
| 23 | +NOTE: A list of length n has n! permutations, so enumerating all possible |
| 24 | +permutations has O(n!) time complexity. |
| 25 | +
|
| 26 | +Algorithm |
| 27 | +--------- |
| 28 | +First, observe that for a sequence that is in descending order, no next larger |
| 29 | +permutation is possible. |
| 30 | +
|
| 31 | + [5, 4, 3, 2, 1] |
| 32 | +
|
| 33 | +So, the next permutation is the reverse of the final permutation. |
| 34 | +
|
| 35 | + [1, 2, 3, 4, 5] |
| 36 | +
|
| 37 | +Next, let's take a look at the permutation before the final permutation: |
| 38 | +
|
| 39 | + [5, 4, 3, 1, 2] |
| 40 | +
|
| 41 | +To get the final permutation we swap 1 and 2. In fact 1 and 2 are the first |
| 42 | +pair of successive numbers which satisfy the condition a[i] > a[i-1]. This is |
| 43 | +another key insight: |
| 44 | +
|
| 45 | + >Given a starting permutation of `a`, the first pair of two successive |
| 46 | + numbers a[i] and a[i−1], which satisfy the condition a[i] > a[i−1] found by |
| 47 | + traversing the array from the right, demarcate the start of the next |
| 48 | + permutation. We can assert that a[i...n-1] are in descending order. |
| 49 | +
|
| 50 | +In order to get the next permutation, we need to replace a[i-1] with the next |
| 51 | +larger number in a[i...n-1]. Said another way, we need to find the smallest |
| 52 | +value a[i...n-1] that is larger than a[i-1]. We will call this value a[j]. |
| 53 | +Swapping these values, a[i-1] and a[j], puts the correct value at index i - 1. |
| 54 | +
|
| 55 | +Next, the sequence a[i...n-1] needs to be rearranged into the lowest possible |
| 56 | +permutation, which is formed by putting its values in ascending order. However, |
| 57 | +since we have already asserted that a[i...n-1] are in descending order, we just |
| 58 | +have to reverse the sequence (an O(n) operation). |
| 59 | +""" |
| 60 | + |
| 61 | + |
| 62 | +class Solution: |
| 63 | + def nextPermutation(self, nums: list[int]) -> None: |
| 64 | + """ |
| 65 | + Do not return anything, modify nums in-place instead. |
| 66 | +
|
| 67 | + 1. Find the pivot: Scan from right to left to find the first index i−1 |
| 68 | + such that nums[i−1] < nums[i]. |
| 69 | +
|
| 70 | + 2. Swap with a just‐larger element: From the right again, find the |
| 71 | + first index j where nums[j] > nums[i−1]. Swap nums[i−1] and nums[j]. |
| 72 | +
|
| 73 | + 3. Reverse the suffix: Finally, reverse the subarray nums[i...n−1]. |
| 74 | + """ |
| 75 | + n = len(nums) |
| 76 | + if n <= 1: |
| 77 | + return None |
| 78 | + |
| 79 | + i = n - 1 |
| 80 | + |
| 81 | + # Find `i` which satisfies the condition nums[i−1] < nums[i]. |
| 82 | + while i > 0 and nums[i - 1] >= nums[i]: |
| 83 | + i -= 1 |
| 84 | + |
| 85 | + # Find the first value in nums[i...n-1], where nums[j] > nums[i-1]. |
| 86 | + if i > 0: |
| 87 | + j = n - 1 |
| 88 | + while nums[j] <= nums[i - 1]: |
| 89 | + j -= 1 |
| 90 | + # Swap nums[i-1] and nums[j]. |
| 91 | + nums[i - 1], nums[j] = nums[j], nums[i - 1] |
| 92 | + |
| 93 | + # Reverse nums[i...n-1]. |
| 94 | + k = n - 1 |
| 95 | + while i < k: |
| 96 | + nums[i], nums[k] = nums[k], nums[i] |
| 97 | + i += 1 |
| 98 | + k -= 1 |
| 99 | + |
| 100 | + return None |
0 commit comments