Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers.
Example 1:
Input: k = 3, n = 7
Output:
[[1,2,4]]
Example 2:
Input: k = 3, n = 9
Output:
[[1,2,6], [1,3,5], [2,3,4]]
解法一:回溯法Language-Java Run Time-1ms
public class Solution {
public List<List<Integer>> combinationSum3(int k, int n) {
List<List<Integer>> res=new ArrayList<List<Integer>>();
recursion(res,new ArrayList<Integer>(),k,n,1);
return res;
}
/**
* Combination Sum III
* @param list:返回的数组
* @param sublist:当前搜索路径
* @param k
* @param n
* @param start:从几开始找,问题开始时显然从1开始找
*/
private void recursion(List<List<Integer>> list,List<Integer> sublist,int k,int n,int start) {
if(k == 1 ) {
if(n < 10) {
List<Integer> sublist2=new ArrayList<Integer>(sublist);
sublist2.add(n);
list.add(sublist2);
/*return语句有两种形式:
* return;
* return expression;
*不带返回值的return语句只能用于返回类型为void的函数。
*在返回类型为void的函数中,return返回语句不是必需的,隐式的return发生在函数的最后一个语句完成时。
*一般情况下,返回类型是void的函数使用return语句是为了引起函数的强制结束,这种return的用法类似于循环结构中的break语句。*/
return;
}
}
else {
/* 注意,如果不转换为double,会导致解空间变小。
* 例如n=7,k=2时如果不转换相当于i<3,如果加double转换相当于i<3.5,前者会遗漏掉i=3的情况。
* 同理如果改为i<=n/k会导致解空间变大。
*/
for(int i=start;i<(double)n/(double)k;i++) {
sublist.add(i);
//递归
recursion(list,sublist,k-1,n-i,i+1);
//回溯
sublist.remove(sublist.size()-1);
}
}
}
}