递归法思路:
首先考虑为什么能用递归(因为存在大问题和小问题之间的关系,大问题:从第 i 个数字到最后一个数字之间找子集,小问题:从第 i+1 个数字到最后一个数字之间找子集)。其次,用递归的三段式:写边界条件(i==n+1,也就是所有的数都被判断完毕),考虑第 i 个数,不考虑第 i 个数。
代码:
C++:
class Solution {
public:
void insert(vector<vector<int>>& res,vector<int>& visit,int len,vector<int>& nums){
vector<int> temp;
for(int i=0;i<len;i++){
if(visit[i]){
temp.push_back(nums[i]);
}
}
res.push_back(temp);
}
void dfs(int i,vector<vector<int>>& res,vector<int>& visit,int len,vector<int>& nums){
//边界条件
if(i==len){
insert(res,visit,len,nums);
return;
}
//选择当前数字
visit[i]=1;
dfs(i+1,res,visit,len,nums);
visit[i]=0;
//不选择当前数字
dfs(i+1,res,visit,len,nums);
}
vector<vector<int>> subsets(vector<int>& nums) {
int len=nums.size();
vector<int> visit(len,0);
vector<vector<int>> res;
dfs(0,res,visit,len,nums);
return res;
}
};
Python:
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
len_nums=len(nums)
visit=[0]*len_nums
res=[]
def insert():
temp=[]
for i in range(len_nums):
if visit[i]:
temp.append(nums[i])
res.append(temp)
def dfs(i):
if i==len_nums:
insert()
return
visit[i]=1
dfs(i+1)
visit[i]=0
dfs(i+1)
dfs(0)
return res
二进制法求解思路:
主要思路就是用二进制来帮助选择元素,拿第一个例子来说,0(000)就是三个元素都没有选择,即[ ];1(001)就是选择了第三个元素,即[3]。所以我们只需要遍历0--1(:1<<n)即可。如果当下遍历到了6(110,这里记为 i ),那么该怎么获取第几个元素被选择了呢,就依次判别 i & (1<< j ),j 的范围是0-len(nums),如果 i 的第 j 位为1,那么说明第 j 位被选择,同时 i & (1<< j )不为0,该位被记录。
代码:
C++:
class Solution {
public:
vector<int> g;
vector<vector<int>> res;
vector<vector<int>> subsets(vector<int>& nums) {
//用二进制来帮助元素选择(0-2^len)
int len=nums.size();
int temp=1<<len;
for(int i=0;i<temp;i++){
g.clear();
for(int j=0;j<len;j++){
if(i & (1<<j)){
g.push_back(nums[j]);
}
}
res.push_back(g);
}
return res;
}
};
Python:
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
g=[]
res=[]
len_nums=len(nums)
temp=1<<len_nums
for i in range(temp):
g.clear()
for j in range(len_nums):
if i&(1<<j):
g.append(nums[j])
res.append(g.copy())
return res
注意这句话:
res.append(g.copy())
res.append(g)
#当您将 g 添加到 res 中时,您实际上是在添加对 g 的引用,而不是它的一个副本。因此,当您清空 g 或者之后对 g 做任何修改时,res 中已经添加的那些 g 的引用也会反映这些修改。