|
| 1 | +# Next Permutation |
| 2 | + |
| 3 | +Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers. |
| 4 | + |
| 5 | +If such an arrangement is not possible, it must rearrange it as the lowest possible order (i.e., sorted in ascending |
| 6 | +order). |
| 7 | + |
| 8 | +The replacement must be in place and use only constant extra memory. |
| 9 | + |
| 10 | +## Constraints |
| 11 | + |
| 12 | +- 1 <= `nums.length` <= 100 |
| 13 | +- 0 <= `nums[i]` <= 100 |
| 14 | + |
| 15 | + |
| 16 | +``` |
| 17 | +Example 1: |
| 18 | +
|
| 19 | +Input: nums = [1,2,3] |
| 20 | +Output: [1,3,2] |
| 21 | +``` |
| 22 | + |
| 23 | +``` |
| 24 | +Example 2: |
| 25 | +
|
| 26 | +Input: nums = [3,2,1] |
| 27 | +Output: [1,2,3] |
| 28 | +``` |
| 29 | + |
| 30 | +``` |
| 31 | +Example 3: |
| 32 | +
|
| 33 | +Input: nums = [1,1,5] |
| 34 | +Output: [1,5,1] |
| 35 | +``` |
| 36 | + |
| 37 | +``` |
| 38 | +Example 4: |
| 39 | +
|
| 40 | +Input: nums = [1] |
| 41 | +Output: [1] |
| 42 | +``` |
| 43 | + |
| 44 | +## Solution |
| 45 | + |
| 46 | +The problem asks us to find the next permutation of a given array of numbers. This is the next “dictionary order” |
| 47 | +(lexicographical) arrangement of the same numbers. We can solve this problem using a two pointers (or more accurately, |
| 48 | +a “two-index”) approach, as it allows us to efficiently find the two critical positions in the array that need to be |
| 49 | +changed. |
| 50 | + |
| 51 | +We use one pointer (or index) to find the “pivot” element we need to increase, and a second pointer to find the |
| 52 | +“successor” element to swap it with. This targeted, two-index approach enables us to perform the minimal change required, |
| 53 | +which is crucial for finding the next permutation and satisfying the in-place, constant-memory constraints. To find the |
| 54 | +next smallest permutation that is larger than the current one, we need to make the smallest possible increase. This is |
| 55 | +done by modifying the “least significant” part of the array (the right-hand side) first. To do this, we make the |
| 56 | +smallest possible increase to the number, working from right to left: |
| 57 | + |
| 58 | +1. **Find the pivot**: We scan from the right to find the first element (pivot) that is smaller than its right neighbor. |
| 59 | + This is the element we will increase. |
| 60 | + |
| 61 | +2. **Find the successor**: We scan from the right again to find the smallest element (successor) that is larger than the |
| 62 | + pivot. |
| 63 | + |
| 64 | +3. **Swap**: We swap the pivot and the successor. |
| 65 | + |
| 66 | +4. **Reverse the suffix**: We reverse the part of the array to the right of the pivot’s original position. This ensures |
| 67 | + the new suffix is in its smallest possible order (ascending). This single reverse operation also cleverly handles |
| 68 | + both possible scenarios: |
| 69 | + - **Case 1 (pivot is found)**: The suffix (from i+1 onward) was previously in descending order. Reversing it sorts it |
| 70 | + into ascending order. This makes the new permutation as small as possible, ensuring it’s the immediate next one. |
| 71 | + - **Case 2 (no pivot is found)**: If the array were already in its largest order (e.g., [3,2,1]), the first loop |
| 72 | + would finish with i=−1. This final step will then reverse from i+1 (which is index 0) to the end, correctly |
| 73 | + transforming the entire array into its smallest possible order (e.g., .[1,2,3]). |
| 74 | + |
| 75 | +Here’s a step-by-step breakdown of the code: |
| 76 | + |
| 77 | +1. We initialize an index i to the second last element of nums. |
| 78 | +2. Next, we iterate backward starting from i to find the “pivot”. This is the rightmost element that can be changed to |
| 79 | + increase the permutation’s size. |
| 80 | +3. Then, we check if a pivot is actually found (i.e., i is greater than or equal to 0). |
| 81 | + - If a pivot is found, we initialize a second index, j, to the last element of nums. |
| 82 | + - Then, we iterate backward from j to find the “successor”. This is the smallest possible number in the suffix that |
| 83 | + we can swap with the pivot. |
| 84 | + - Once the “successor” is found, we swap the pivot nums[i] with its successor nums[j]. This guarantees the new |
| 85 | + permutation is larger than the original. |
| 86 | +4. Finally, we reverse the portion of the array that comes after the pivot’s original index i (i.e., from index i + 1 |
| 87 | + to the end). |
| 88 | + |
| 89 | +### Time Complexity |
| 90 | + |
| 91 | +The time complexity of this solution is O(n), because in the worst-case scenario, we perform a single pass to find the |
| 92 | +pivot, another single pass to find the element to swap, and a final pass to reverse a part of the array. |
| 93 | + |
| 94 | +### Space Complexity |
| 95 | + |
| 96 | +The solution’s space complexity is O(1), as the permutation is done in-place, and only a constant amount of extra memory |
| 97 | +is used for variables. |
0 commit comments