题目:
Given a set of distinct integers, nums, return all possible subsets (the power set).
Note: The solution set must not contain duplicate subsets.
Example:
Input: nums = [1,2,3]
Output:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
解法1:
回溯法
c++:
与平常的回溯法相比,直接没有判断条件,直接加入path,且没有return语句
res.push_back(path);
nums = [1,2,3]
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> res;
vector<int> path;
DFS(nums, path, res, 0);
return res;
}
void DFS(vector<int>& nums, vector<int>& path,vector<vector<int>>& res,int start){
res.push_back(path);
for(int i = start; i < nums.size(); ++i){
path.push_back(nums[i]);
DFS(nums, path, res, i+1);
path.pop_back();
}
}
};
java;
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
DFS(nums, path, res, 0);
return res;
}
private void DFS(int[] nums, List<Integer> path,List<List<Integer>> res,int start){
res.add(new ArrayList<>(path));
for(int i = start; i < nums.length ; ++i){
path.add(nums[i]);
DFS(nums, path, res, i+1);
path.remove(path.size() - 1);
}
}
}
python:
class Solution(object):
def subsets(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
res = []
self.DFS(nums, [], res, 0)
return res
def DFS(self, nums, path, res,start):
res.append(path)
for i in xrange(start, len(nums)):
self.DFS(nums, path + [nums[i]], res, i+1)
解法2:
回溯法变体
对每一个元素都有选择或者不选择,不选择则不添加,所有的元素都加完即得到结果
[]
/ \
/ \
/ \
[1] []
/ \ / \
/ \ / \
[1 2] [1] [2] []
/ \ / \ / \ / \
[1 2 3] [1 2] [1 3] [1] [2 3] [2] [3] []
图来自:[LeetCode] 78. Subsets 子集合
c++:
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> res;
vector<int> path;
DFS(nums, path, res, 0);
return res;
}
void DFS(vector<int>& nums, vector<int>& path,vector<vector<int>>& res,int start){
if(start == nums.size()){
res.push_back(path);
return;
}
DFS(nums, path, res, start+1);
path.push_back(nums[start]);
DFS(nums, path, res, start+1);
path.pop_back();
}
};
java:
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
DFS(nums, path, res, 0);
return res;
}
private void DFS(int[] nums, List<Integer> path,List<List<Integer>> res,int start){
if(start == nums.length){
res.add(new ArrayList<>(path));
return;
}
DFS(nums, path, res, start+1);
path.add(nums[start]);
DFS(nums, path, res, start+1);
path.remove(path.size() - 1);
}
}
python:
class Solution(object):
def subsets(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
res = []
self.DFS(nums, [], res, 0)
return res
def DFS(self, nums, path, res,start):
if start == len(nums):
res.append(path)
return
self.DFS(nums, path, res, start+1)
self.DFS(nums, path + [nums[start]], res, start+1)
解法3:
迭代法
初始化首先为空集合,然后每一次复制结果中的元素,然后再原有的集合中加入新元素
c++:
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> res = {{}};
for(int num : nums){
int size = res.size();
for(int i = 0; i < size; i++){
res.push_back(res[i]);
res.back().push_back(num);
}
}
return res;
}
};
java:
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
res.add(new ArrayList<>());
for(int num : nums){
int size = res.size();
for(int i = 0; i < size; i++){
res.add(new ArrayList<>(res.get(i)));
res.get(res.size()-1).add(num);
}
}
return res;
}
}
python:
class Solution(object):
def subsets(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
res = [[]]
for num in nums:
res += [ r + [num] for r in res]
return res
解法4:
二进制法
nums = [1,2,3] 总共有23种组合 正好对应0-7 8个数字
8个数字的二进制形式分别对应一种集合如下图所示
图来自:[LeetCode] 78. Subsets 子集合
c++:
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> res;
int size = 1 << nums.size();
for(int i = 0; i < size; i++){
vector<int> path = convertIntToSet(nums,i);
res.push_back(path);
}
return res;
}
vector<int> convertIntToSet(vector<int>& nums,int k){
vector<int> sub;
int idx = 0;
for(int i = k; i > 0; i >>= 1){
if(i & 1 == 1){
sub.push_back(nums[idx]);
//cout << nums[idx] << endl;
}
idx++;
}
return sub;
}
};
java:
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
int size = 1 << nums.length;
for(int i = 0; i < size; i++){
List<Integer> path = convertIntToSet(nums,i);
res.add(path);
}
return res;
}
List<Integer> convertIntToSet(int[] nums,int k){
List<Integer> sub = new ArrayList<>();
int idx = 0;
for(int i = k; i > 0; i >>= 1){
if((i & 1) == 1){
sub.add(nums[idx]);
}
idx++;
}
return sub;
}
}
python:
class Solution(object):
def subsets(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
res = []
#nums.sort()
for i in xrange(1<<len(nums)):
tmp = []
j = 0
while i > 0:
if i & 1:
tmp.append(nums[j])
j += 1
i >>= 1
res.append(tmp)
# print res
return res