216. Combination Sum III

题目大意:将k个不同的数字相加,使得所求的和为n,要求这些数字只能从1到9中间取,并且不能重复。求出所有满足的情况,并且按从小到的顺序排列后存入列表。例如:k=3,n=7,结果应为:[[1,2,4]]。再比如:k = 3, n = 9,结果为:[[1,2,6], [1,3,5], [2,3,4]]。

解题思路:此题很显然要用递归。递归返回(存入列表)的条件为:选得的数字个数等于k,并且sum等于n。要选的第一个数字(序列中最小值)从1到9进行遍历,先选1可以吗?接着先选2?……一直到9。

具体做法:实现一个帮助函数combinationSum3Helper(int k, int sum, int n, int i, vector<int>& tmp, vector<vector<int> >& result)。

每次新调用一个帮助函数k都减1,一直减到0说明要求的k个数字名额满了。

sum存储当前所得的和,等于n时说明满足。

i表示可选的数字为i到9。

result存储最终结果。

tmp用来存储已经选得的数字,如果最终满足了条件sum == n && k == 0,就能把tmp存入result。注意tmp的回溯,每一个帮助函数返回时都会有一次pop_back()。

代码如下:

 1 class Solution {
 2 public:
 3     vector<vector<int>> combinationSum3(int k, int n) {
 4         vector<int> tmp;
 5         vector<vector<int> > result;
 6         combinationSum3Helper(k, 0, n, 1, tmp, result);
 7         return result;
 8     }
 9     void combinationSum3Helper(int k, int sum, int n, int i, vector<int>& tmp, vector<vector<int> >& result)
10     {
11         if(sum == n && k == 0)
12         {
13             result.push_back(tmp);
14             return;
15         }
16         else if(sum > n || k <= 0) return;
17         
18         for(int j = i; j <= 9; ++j)//从i到9中间选数字
19         {
20             tmp.push_back(j); 
21             combinationSum3Helper(k-1, sum+j, n, j+1, tmp, result);//如果说该句结束了,要么是当前元素不可能满足,要么是已经写入了result
22             tmp.pop_back();//保证了每次写入result以后清空当前的tmp,或者不可能满足的情况下清空当前的tmp
23         }
24     }
25 };
原文地址:https://www.cnblogs.com/jingyuewutong/p/5583497.html