思考过程:
遍历数组,如果当前数字i和目标数字t相等,那么把当前数字加入结果,
如果不等,那么可以先求f(nums,t-i)的结果,然后每一条list再加上i后,再放入结果。当t<=0时终止递归。
需要注意的是直接加会产生重复数据,所以每次加入到结果页时需要判断是否已经加过了,可以用对list排序再取hash的方式来判断。
代码实现:
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> ans = new ArrayList<>();
Set<Integer> set = new HashSet<>();
boolean add;
if (target > 0) {
for (int i : candidates) {
if (i == target) {
List<Integer> tem = new ArrayList<>();
tem.add(i);
ans.add(tem);
} else {
List<List<Integer>> list = combinationSum(candidates, target - i);
for (List<Integer> tem : list) {
add = false;
for (int j = 0; j < tem.size(); j++) {
if (i <= tem.get(j)) {
tem.add(j, i);
add = true;
break;
}
}
if (!add) {
tem.add(i);
}
if (!set.contains(tem.hashCode())) {
ans.add(tem);
set.add(tem.hashCode());
}
}
}
}
}
return ans;
}
执行结果:
效率不太理想。
算法复杂度分析:
因为有三个for循环,所以时间复杂度是O(n³)。
空间复杂度O(n)
官方代码的执行结果