目录
回溯问题有两种思考方式,一种是对于给定集合的每个元素,你是选还是不选,另一种是每个位置必须选一个数,你挑一个选就行了.但这种挑选一定是有序的挑
子集
子集
1,选或不选
class Solution {
public:
vector<vector<int>>ans;
vector<int>path;
void dfs(int i,vector<int>&nums)
{
if(i==nums.size())
{
ans.push_back(path);
return;
}
dfs(i+1,nums);//不选
path.push_back(nums[i]);
dfs(i+1,nums);
path.pop_back();
}
vector<vector<int>> subsets(vector<int>& nums) {
dfs(0,nums);
return ans;
}
};
2.枚举选哪个
class Solution {
public:
vector<vector<int>>ans;
vector<int>path;
void dfs(int i,vector<int>&nums)
{
ans.push_back(path);
for(int j=i;j<nums.size();j++)
{
path.push_back(nums[j]);
dfs(j+1,nums);
path.pop_back();//当前问题从>=i中的数字取一个j,下一个子问题从>=j+1的元素中取一个数
}
}
vector<vector<int>> subsets(vector<int>& nums) {
dfs(0,nums);
return ans;
}
};
组合
组合
1.选或不选
class Solution {
public:
vector<vector<int>>ans;
vector<int>path;
void dfs(int i,int n,int k)
{
if(path.size()==k)
{
ans.push_back(path);
return;
}
if(i==n+1)return;
dfs(i+1,n,k);
path.push_back(i);
dfs(i+1,n,k);
path.pop_back();
}
vector<vector<int>> combine(int n, int k) {
dfs(1,n,k);
return ans;
}
};
2.枚举选哪个
class Solution {
public:
vector<vector<int>>ans;
vector<int>path;
void dfs(int i,int n,int k)
{
int d=k-path.size();
if(path.size()==k)
{
ans.push_back(path);
return;
}
if(i<d)return;
for(int j=i;j>=1;j--)//当前为题从[1,i]中选一个数j,子问题从[1,j-1]中选一个数
{
path.push_back(j);
dfs(j-1,n,k);
path.pop_back();
}
}
vector<vector<int>> combine(int n, int k) {
dfs(n,n,k);
return ans;
}
};