🧠
Brute Force (Generate All Permutations and Find Next)
💡 This approach exists to build intuition by brute forcing all permutations and then finding the next one. It is impractical for large inputs but helps understand the problem deeply.
Intuition
Generate all permutations of the array, sort them lexicographically, then find the current permutation and return the next one in order.
Algorithm
- Generate all permutations of the input array.
- Sort all permutations lexicographically.
- Find the index of the current permutation in the sorted list.
- Return the permutation at the next index, or the first if current is last.
💡 This algorithm is conceptually simple but computationally expensive because generating all permutations grows factorially.
from itertools import permutations
def next_permutation(nums):
perms = sorted(set(permutations(nums)))
curr = tuple(nums)
idx = perms.index(curr)
next_idx = (idx + 1) % len(perms)
nums[:] = perms[next_idx]
# Driver code
if __name__ == '__main__':
arr = [1,2,3]
next_permutation(arr)
print(arr) # Output: [1,3,2]
Line Notes
from itertools import permutationsImport permutations to generate all permutations easily
perms = sorted(set(permutations(nums)))Generate all unique permutations and sort them lex order
idx = perms.index(curr)Find the current permutation's index in the sorted list
nums[:] = perms[next_idx]Modify input array in-place to the next permutation
import java.util.*;
public class NextPermutationBrute {
public static void nextPermutation(int[] nums) {
List<List<Integer>> perms = new ArrayList<>();
permute(nums, 0, perms);
perms.sort((a,b) -> {
for (int i = 0; i < a.size(); i++) {
if (!a.get(i).equals(b.get(i))) return a.get(i) - b.get(i);
}
return 0;
});
List<Integer> curr = new ArrayList<>();
for (int num : nums) curr.add(num);
int idx = perms.indexOf(curr);
List<Integer> next = perms.get((idx + 1) % perms.size());
for (int i = 0; i < nums.length; i++) nums[i] = next.get(i);
}
private static void permute(int[] nums, int start, List<List<Integer>> perms) {
if (start == nums.length) {
List<Integer> perm = new ArrayList<>();
for (int num : nums) perm.add(num);
if (!perms.contains(perm)) perms.add(perm);
return;
}
for (int i = start; i < nums.length; i++) {
swap(nums, start, i);
permute(nums, start + 1, perms);
swap(nums, start, i);
}
}
private static void swap(int[] nums, int i, int j) {
int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp;
}
// Driver code
public static void main(String[] args) {
int[] arr = {1,2,3};
nextPermutation(arr);
System.out.println(Arrays.toString(arr)); // Output: [1,3,2]
}
}
Line Notes
List<List<Integer>> perms = new ArrayList<>();Store all permutations generated
permute(nums, 0, perms);Generate all permutations recursively
perms.sort((a,b) -> {...});Sort permutations lex order using comparator
int idx = perms.indexOf(curr);Find current permutation index to get next
#include <bits/stdc++.h>
using namespace std;
void permute(vector<int>& nums, int start, vector<vector<int>>& perms) {
if (start == (int)nums.size()) {
perms.push_back(nums);
return;
}
for (int i = start; i < (int)nums.size(); i++) {
swap(nums[start], nums[i]);
permute(nums, start + 1, perms);
swap(nums[start], nums[i]);
}
}
void nextPermutation(vector<int>& nums) {
vector<vector<int>> perms;
permute(nums, 0, perms);
sort(perms.begin(), perms.end());
auto it = find(perms.begin(), perms.end(), nums);
int idx = distance(perms.begin(), it);
nums = perms[(idx + 1) % perms.size()];
}
int main() {
vector<int> arr = {1,2,3};
nextPermutation(arr);
for (int x : arr) cout << x << ' '; // Output: 1 3 2
cout << '\n';
return 0;
}
Line Notes
void permute(vector<int>& nums, int start, vector<vector<int>>& perms)Recursive function to generate all permutations
sort(perms.begin(), perms.end());Sort all permutations lexicographically
auto it = find(perms.begin(), perms.end(), nums);Find current permutation's position
nums = perms[(idx + 1) % perms.size()];Assign next permutation or wrap to first
function permute(nums, start, perms) {
if (start === nums.length) {
perms.push(nums.slice());
return;
}
for (let i = start; i < nums.length; i++) {
[nums[start], nums[i]] = [nums[i], nums[start]];
permute(nums, start + 1, perms);
[nums[start], nums[i]] = [nums[i], nums[start]];
}
}
function nextPermutation(nums) {
let perms = [];
permute(nums, 0, perms);
perms.sort((a,b) => {
for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i]) return a[i] - b[i];
}
return 0;
});
let currStr = nums.join(',');
let idx = perms.findIndex(p => p.join(',') === currStr);
let next = perms[(idx + 1) % perms.length];
for (let i = 0; i < nums.length; i++) nums[i] = next[i];
}
// Driver code
let arr = [1,2,3];
nextPermutation(arr);
console.log(arr); // Output: [1,3,2]
Line Notes
function permute(nums, start, perms)Recursive helper to generate permutations
perms.sort((a,b) => {...});Sort permutations lex order for indexing
let idx = perms.findIndex(p => p.join(',') === currStr);Find current permutation index
for (let i = 0; i < nums.length; i++) nums[i] = next[i];Overwrite input array in-place
TimeO(n! * n log n) due to generating all permutations and sorting
SpaceO(n! * n) to store all permutations
Generating all permutations is factorial in n, sorting them adds n log n factor, and storing them requires large memory.
💡 For n=10, this means over 3 million permutations, which is impractical to compute or store.
Interview Verdict: TLE
This approach is too slow for large inputs but helps understand the problem and verify correctness on small inputs.