Problem Statement
A permutation of an array of integers is an arrangement of its members into a sequence or linear order.
- For example, for arr = [1,2,3], the following are all the permutations of arr: [1,2,3], [1,3,2], [2, 1, 3], [2, 3, 1], [3,1,2], [3,2,1].
The next permutation of an array of integers is the next lexicographically greater permutation of its integer. More formally, if all the permutations of the array are sorted in one container according to their lexicographical order, then the next permutation of that array is the permutation that follows it in the sorted container. If such arrangement is not possible, the array must be rearranged as the lowest possible order (i.e., sorted in ascending order).
- For example, the next permutation of arr = [1,2,3] is [1,3,2].
- Similarly, the next permutation of arr = [2,3,1] is [3,1,2].
- While the next permutation of arr = [3,2,1] is [1,2,3] because [3,2,1] does not have a lexicographical larger rearrangement.
Given an array of integers nums
, find the next permutation of nums
.
The replacement must be in place and use only constant extra memory.
LeetCode:
Constraints:
1 <= nums.length <= 100
0 <= nums[i] <= 100
Examples
Example 1:
Input: nums = [1, 2, 3]
Output: [1, 3, 2]
Example 2:
Input: nums = [3, 2, 1]
Output: [1, 2, 3]
Example 3:
Input: nums = [1, 1, 5]
Output: [1, 5, 1]
Different Approaches
1️⃣ Brute Force Using STL (Not allowed in interviews where STL usage is restricted)
Intuition:
Use the C++ Standard Library function which handles all the logic internally
Approach:
- Just call
std::next_permutation()
on the vector.
Code:
#include <algorithm>
void nextPermutation(vector<int>& nums) {
next_permutation(nums.begin(), nums.end());
}
Complexity Analysis:
- Time Complexity:
O(n)
- Space Complexity:
O(1)
2️⃣ Generate All Permutations
Intuition:
Generate all permutations and find the next one in sorted order.
Approach:
- Generate all permutations.
- Sort them.
- Find the current permutation's index.
- Return the next one.
Code:
3️⃣ Optimal Approach
Intuition:
Find the pivot where order breaks and swap with the smallest number greater than it from the right side, then reverse the right half.
Approach:
- Traverse from right to left to find the first decreasing element
nums[i]
. - Find the next larger element
nums[j] > nums[i]
. - Swap
nums[i]
andnums[j]
. - Reverse the elements from
i + 1
to the end.
Code:
void nextPermutation(vector<int>& nums) {
int n = nums.size();
int i = n - 2;
// Step 1: Find first decreasing element
while (i >= 0 && nums[i] >= nums[i + 1]) {
i--;
}
if (i >= 0) {
// Step 2: Find next greater element on right
int j = n - 1;
while (nums[j] <= nums[i]) {
j--;
}
swap(nums[i], nums[j]); // Step 3: Swap
}
// Step 4: Reverse suffix
reverse(nums.begin() + i + 1, nums.end());
}
Complexity Analysis:
- Time Complexity:
O(n)
- Space Complexity:
O(1)