Generate All Permutations: Backtracking with Swap
Advertisement
Generate All Permutations
Approach 1: Used Array
def permute(nums):
result = []
used = [False] * len(nums)
def bt(current):
if len(current) == len(nums):
result.append(current[:])
return
for i in range(len(nums)):
if used[i]: continue
used[i] = True
current.append(nums[i])
bt(current)
current.pop()
used[i] = False
bt([])
return result
# Permutations II (with duplicates)
def permuteUnique(nums):
nums.sort()
result = []
used = [False] * len(nums)
def bt(current):
if len(current) == len(nums):
result.append(current[:])
return
for i in range(len(nums)):
if used[i]: continue
# Skip: same value as previous, and previous was NOT used
# (previous was used in a different branch, this creates duplicate)
if i > 0 and nums[i] == nums[i-1] and not used[i-1]:
continue
used[i] = True
current.append(nums[i])
bt(current)
current.pop()
used[i] = False
bt([])
return result
Approach 2: In-Place Swap
def permute_swap(nums):
result = []
def bt(start):
if start == len(nums):
result.append(nums[:])
return
for i in range(start, len(nums)):
nums[start], nums[i] = nums[i], nums[start]
bt(start + 1)
nums[start], nums[i] = nums[i], nums[start]
bt(0)
return result
C++ Implementation
#include <bits/stdc++.h>
using namespace std;
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> result;
sort(nums.begin(), nums.end());
do {
result.push_back(nums);
} while (next_permutation(nums.begin(), nums.end()));
return result;
}
// Manual backtracking
vector<vector<int>> permuteManual(vector<int> nums) {
vector<vector<int>> result;
function<void(int)> bt = [&](int start) {
if (start == (int)nums.size()) {
result.push_back(nums);
return;
}
for (int i = start; i < (int)nums.size(); i++) {
swap(nums[start], nums[i]);
bt(start + 1);
swap(nums[start], nums[i]);
}
};
bt(0);
return result;
}
Java Implementation
import java.util.*;
public class Permutations {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
backtrack(nums, new boolean[nums.length], new ArrayList<>(), result);
return result;
}
void backtrack(int[] nums, boolean[] used, List<Integer> curr, List<List<Integer>> result) {
if (curr.size() == nums.length) {
result.add(new ArrayList<>(curr));
return;
}
for (int i = 0; i < nums.length; i++) {
if (used[i]) continue;
used[i] = true;
curr.add(nums[i]);
backtrack(nums, used, curr, result);
curr.remove(curr.size() - 1);
used[i] = false;
}
}
}
Complexity
- Time: O(n! * n) — n! permutations, O(n) to copy each
- Space: O(n) recursion depth
Advertisement