先来看题目描述:
题解思路:
先来做一下重点概述:
——当一个题有多个步骤,而每个步骤有多种方法,且需要列出所有解,可以考虑用回溯
——而回溯是基于树的一种深度优先搜索
——上题中的组合问题中【1,2,3】和【1,3,2】是没有区别的,这是要首先明白的
题解:
既然是基于树的,那么先画出树来,假设n=4,k=2
当我们选择 1 时,就只能在【2,3,4】里面选择;当我们选择其中一个时,比如2,【1,2】符合要求,把他存储下来。这是我们遍历完一种状况,这时就需要回溯到上一种状况,再去选择下一个数,直到存储好【1,4】。
这时需要在回溯到根节点,再去选择 2 ,这时我们就只能在【3,4】里面选择了。因为1的情况在前面已经存储好了。接下来就和上面相同了。
类推,直到遍历完所有可能。
附上图:
为了能节约时间,可以进行剪枝。
下面附上代码:
class Solution {
public:
vector<int>temp;
vector<vector<int>>arr;
vector<vector<int>> combine(int n, int k) {
dfs(1,n,k);
return arr;
}
void dfs(int cur,int n,int k)
{
if(temp.size()==k) // 满足相应长度的组合,装进arr中去
{
arr.push_back(temp);
return;
}
if(temp.size()+(n-cur+1)<k) //剪枝
{
return;
}
temp.push_back(cur); //考虑需要这个元素
dfs(cur+1,n,k);
temp.pop_back();//考虑不需要,回溯
dfs(cur+1,n,k);
}
};