Generate All Subsets: Power Set with Backtracking
Advertisement
Generate All Subsets
Algorithm: Include/Exclude
At each index, decide: include this element or skip it.
Python Implementation
def subsets(nums):
result = []
def bt(start, current):
result.append(current[:]) # snapshot at every node
for i in range(start, len(nums)):
current.append(nums[i])
bt(i + 1, current)
current.pop() # backtrack
bt(0, [])
return result
print(subsets([1, 2, 3]))
# [[], [1], [1,2], [1,2,3], [1,3], [2], [2,3], [3]]
# Subsets II (with duplicates): sort + skip same sibling
def subsetsWithDup(nums):
nums.sort()
result = []
def bt(start, current):
result.append(current[:])
for i in range(start, len(nums)):
if i > start and nums[i] == nums[i-1]:
continue # skip duplicate at same level
current.append(nums[i])
bt(i + 1, current)
current.pop()
bt(0, [])
return result
# Bitmask approach
def subsets_bitmask(nums):
n = len(nums)
result = []
for mask in range(1 << n):
subset = [nums[i] for i in range(n) if mask >> i & 1]
result.append(subset)
return result
C++ Implementation
#include <bits/stdc++.h>
using namespace std;
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> result;
vector<int> current;
function<void(int)> bt = [&](int start) {
result.push_back(current);
for (int i = start; i < (int)nums.size(); i++) {
current.push_back(nums[i]);
bt(i + 1);
current.pop_back();
}
};
bt(0);
return result;
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<vector<int>> result;
vector<int> current;
function<void(int)> bt = [&](int start) {
result.push_back(current);
for (int i = start; i < (int)nums.size(); i++) {
if (i > start && nums[i] == nums[i-1]) continue;
current.push_back(nums[i]);
bt(i + 1);
current.pop_back();
}
};
bt(0);
return result;
}
Java Implementation
import java.util.*;
public class Subsets {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
backtrack(nums, 0, new ArrayList<>(), result);
return result;
}
void backtrack(int[] nums, int start, List<Integer> current, List<List<Integer>> result) {
result.add(new ArrayList<>(current));
for (int i = start; i < nums.length; i++) {
current.add(nums[i]);
backtrack(nums, i + 1, current, result);
current.remove(current.size() - 1);
}
}
}
JavaScript Implementation
function subsets(nums) {
const result = [];
function bt(start, current) {
result.push([...current]);
for (let i = start; i < nums.length; i++) {
current.push(nums[i]);
bt(i + 1, current);
current.pop();
}
}
bt(0, []);
return result;
}
Complexity
- Time: O(2^n * n) — 2^n subsets, each takes O(n) to copy
- Space: O(n) recursion depth
Advertisement