|
| 1 | +# 31. Next Permutation |
| 2 | + |
| 3 | +**Difficulty:** *Medium* |
| 4 | +**Category:** *Arrays, Permutations, Greedy* |
| 5 | +**Leetcode Link:** [Problem Link](https://leetcode.com/problems/next-permutation/) |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## 📝 Introduction |
| 10 | + |
| 11 | +*Given an array Arr[] of integers, rearrange the numbers into the lexicographically next greater permutation of numbers. |
| 12 | +If such an arrangement is not possible, rearrange it to the lowest possible order (i.e., sorted in ascending order).* |
| 13 | + |
| 14 | +*Constraints typically include:<br> |
| 15 | +- All integers may be distinct or contain duplicates.<br> |
| 16 | +- The transformation must be done in-place with only constant extra memory.* |
| 17 | + |
| 18 | +--- |
| 19 | + |
| 20 | +## 💡 Approach & Key Insights |
| 21 | + |
| 22 | +*There are three main approaches to solve this problem:<br> |
| 23 | +- Brute Force: Generate all permutations and pick the next.<br> |
| 24 | +- In-Built Function: Use next_permutation() if language provides it.<br> |
| 25 | +- Optimal: Use the standard algorithm to compute the next permutation by identifying a break point, swapping, and reversing.* |
| 26 | + |
| 27 | +--- |
| 28 | + |
| 29 | +## 🛠️ Breakdown of Approaches |
| 30 | + |
| 31 | +### 1️⃣ Brute Force / Naive Approach |
| 32 | + |
| 33 | +- **Explanation:** *Generate all permutations of the array, sort them, and locate the input permutation. Return the next one in sequence. If not found or if it's the last permutation, return the first (sorted array).* |
| 34 | +- **Time Complexity:** *O(N! × N) – N! permutations each of length N.* |
| 35 | +- **Space Complexity:** *O(1) – ignoring recursion stack used for generating permutations.* |
| 36 | +- **Example/Dry Run:** |
| 37 | + |
| 38 | +```plaintext |
| 39 | +Input: [1, 2, 3] |
| 40 | +All permutations: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ] |
| 41 | +Current permutation: [1,2,3] |
| 42 | +Next permutation: [1,3,2] |
| 43 | +``` |
| 44 | + |
| 45 | +### 2️⃣ Language Built-in (C++ std::next_permutation) |
| 46 | + |
| 47 | +- **Explanation:** *C++ provides next_permutation() which directly modifies the array to the next permutation.* |
| 48 | +- **Time Complexity:** *O(N) – internally optimized.* |
| 49 | +- **Space Complexity:** *O(1).* |
| 50 | +- **Example:** |
| 51 | + |
| 52 | +```cpp |
| 53 | +std::vector<int> nums = {1, 2, 3}; |
| 54 | +std::next_permutation(nums.begin(), nums.end()); |
| 55 | +// nums is now [1, 3, 2] |
| 56 | +``` |
| 57 | +
|
| 58 | +### 3️⃣ Optimal Approach |
| 59 | +
|
| 60 | +- **Explanation:** |
| 61 | + 1. Find the break-point: The first index i from the back where arr[i] < arr[i+1]. |
| 62 | + 2. If no such index exists, reverse the whole array (it was the last permutation). |
| 63 | + 3. Else, find the smallest number greater than arr[i] from the right half, swap it with arr[i]. |
| 64 | + 4. Reverse the subarray from i+1 to end. |
| 65 | +
|
| 66 | +- **Time Complexity:** *O(3N) = O(N) – each of the three steps (finding break-point, finding next greater, reversing) takes O(N).* |
| 67 | +- **Space Complexity:** *O(1) – all operations are done in-place.* |
| 68 | +- **Example/Dry Run:** |
| 69 | +
|
| 70 | +```plaintext |
| 71 | +Input: [1, 2, 3] |
| 72 | +
|
| 73 | +Step 1: Find break-point: 2 < 3 at index 1 → i = 1 |
| 74 | +Step 2: Find element just greater than arr[i]: 3 at index 2 |
| 75 | +Step 3: Swap 2 and 3 → [1, 3, 2] |
| 76 | +Step 4: Reverse from i+1 = 2 to end → Already sorted |
| 77 | +
|
| 78 | +Output: [1, 3, 2] |
| 79 | +``` |
| 80 | + |
| 81 | +--- |
| 82 | + |
| 83 | +## 📊 Complexity Analysis |
| 84 | + |
| 85 | +| Approach | Time Complexity | Space Complexity | |
| 86 | +| -------------- | ----------------- | ---------------- | |
| 87 | +| Brute Force | O(N! × N) | O(1) | |
| 88 | +| In-Built | O(N) | O(1) | |
| 89 | +| Optimal | O(N) | O(1) | |
| 90 | + |
| 91 | +--- |
| 92 | + |
| 93 | +## 📉 Optimization Ideas |
| 94 | + |
| 95 | +*The optimal solution is already efficient for all constraints. |
| 96 | +You may consider early exits in case the array is already in decreasing order to avoid redundant operations.* |
| 97 | + |
| 98 | +--- |
| 99 | + |
| 100 | +## 📌 Example Walkthroughs & Dry Runs |
| 101 | + |
| 102 | +```plaintext |
| 103 | +Example 1: |
| 104 | +Input: [1, 3, 2] |
| 105 | +Break-point: index 0 (1 < 3) |
| 106 | +Swap with next greater: swap 1 and 2 → [2, 3, 1] |
| 107 | +Reverse after index 0 → [2, 1, 3] |
| 108 | +Output: [2, 1, 3] |
| 109 | +
|
| 110 | +Example 2: |
| 111 | +Input: [3, 2, 1] |
| 112 | +Break-point: None (fully decreasing) |
| 113 | +Reverse entire array → [1, 2, 3] |
| 114 | +Output: [1, 2, 3] |
| 115 | +``` |
| 116 | + |
| 117 | +--- |
| 118 | + |
| 119 | +## 🔗 Additional Resources |
| 120 | + |
| 121 | +- [C++ next_permutation documentation](https://en.cppreference.com/w/cpp/algorithm/next_permutation) |
| 122 | + |
| 123 | +--- |
| 124 | + |
| 125 | +Author: Neha Amin <br> |
| 126 | +Date: 19/07/2025 |
0 commit comments