2018.3.1 17:06 第一篇博客
Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.
For example,
If n = 4 and k = 2, a solution is:
[ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]这道题我用的是深度优先搜索 (DFS),深度优先搜索的思维与常人的思维方式比较接近,比较容易理解,甚至在某些场合有些像(聪明的)枚举。
示例有些过于简单,不妨构造一个稍显复杂的例子,如取n=6 , k=4的情况:
显然首先第一组满足情况的是:
① 1,2,3,4 那么也不难有规律地写出第二组,就是1,2,3,4 ,变成
② 1,2,3,5 可以发现有一个删除最后一位数字的步骤,可以用DFS递归操作后进行pop_back()操作
class Solution {
public:
vector<vector<int>> combine(int n, int k) {
if(n < k || k == 0) return result;
dfs(1,0,n,k);
return result;
}
private:
vector<int> solution;
vector<vector<int>> result;
void dfs(int start , int num , int n , int k)
{
if(num == k)
{
result.push_back(solution);
return;
}
for(int i = start ; i <= n ; i++)
{
solution.push_back(i);
dfs(++start,num+1,n,k);
solution.pop_back();
}
}
};
值得注意的是dfs(++start,num+1,n,k); ++start不能改成start+1,如果改成start+1,在递归返回的时候,会发生重复,具体部分情况如下图所示:
这里的[1,2,3,X](X代表比3大的数),递归返回到[1,2,4,Y]的时候发生了问题,由于start+1在返回时start不会改变,所以这里start=3,故再次进入递归时候Y依旧从4开始,如果改成++start,返回后的start=4,故再次进入递归时候Y会从5开始,从而避免了重复。