就是一个很明显的dfs的题目,但是我还是不是特别能写出来,我本来想dfs里面写三个参数,但是总差点感觉。
分析如下:
花一个图吧,其实还是有一点回溯的过程。其实脑子里面要模拟出树的过程。
我也是阅读别人的大概写出的,贴上一贴之前的写得题目:
Acwing-842 排列组合,这一题没有限制组合后数的位数
class Solution {
public:
vector<vector<int>> ans;
//记录路径
vector<int> path;
void dfs(int n,int k,int u,int start){
//传入数字,数组的大小,从什么时候开始
//其实就是一个路径的选择,所有的数都组合了,最后一步筛选出来
if(u==k){
//把每一次的路径压进去
ans.push_back(path);
//return;
}
//start是一个其实的过程,如果start的组合全选择完了
//那么换一个数字
for(int i=start;i<=n;i++){
path.push_back(i);
dfs(n,k,u+1,i+1);//此时的位数+1;
path.pop_back();
}
}
vector<vector<int>> combine(int n, int k) {
dfs(n,k,0,1);
//k表示的是层数,同样表示的是位数
// 四个参数分别表示为:组合的数的位数应该是是[1,n]
// 数的位数为k,
// 从第0为开始选
// 其实的数组为1,
return ans;
}
};
我dfs有几点是比较关注的,(1)参数选择,(2)回溯的过程,(3)优化过程存在剪枝
分析如下:
这一题就是在限制位数的情况下,然后选出组合数。
(1)返回的参数肯定是返回一个二维数组的,定义一个答案数组,然后第一位记录整条路经,第二位记录的是整条路径的具体细节。使用path记录dfs的路径
(2)dfs选择的参数,肯定两个参数少不了,n,k.分别表示的是数的范围,n表示的是选择数的范围是[1,n].k表示的是数的位数范围
(3)k的范围就是为了最后dfs跳出来
(4)选出start开始,也就是首先的组合肯定有,算是dfs的入口
(5)u是位数的记录,到最后的过程与k比较,使得bfs走到结尾。
(6)一条路径走完之后,然后就要弹出来,算是回溯的过程