一、问题
使用回溯搜索法,一层一层去寻找数组中满足和为target的组合,写完算法如下:
三个案例均通过了,可提交代码时报错:
class Solution {
List<List<Integer>> resList = new LinkedList<>();
List<Integer> path = new LinkedList<>();
int sum = 0;
public List<List<Integer>> combinationSum(int[] candidates, int target) {
backstacking(candidates, target, 0);
return resList;
}
public void backstacking(int[] candidates, int target, int index) {
if (sum == target) {
resList.add(new LinkedList<>(path));
return;
}
for (int i = index; i < candidates.length; i++) {
// 如果 sum + candidates[i] > target 就终止遍历
if (sum + candidates[i] > target) break;
sum += candidates[i];
path.add(candidates[i]);
backstacking(candidates, target, i);
//回溯
path.removeLast();
sum -= candidates[i];
}
}
}
案例通过:
提交结果:
二、分析问题
剪枝优化:和大于target,就可以结束本轮for循环的遍历。
结合报错案例:candidates = [8, 7, 4, 3],target = 11, 8 + 7 > 11,就结束本次for循环了,没找到组合,但实际上8 + 3 = 11,有组合[8, 3],问题就出在这里;
错误原因在于:数组candidates不是升序的,即使当前元素和大于target,后面也可能有更小的元素相加等于target,所以不能结束本轮for循环;
for (int i = index; i < candidates.length; i++) {
// 如果 sum + candidates[i] > target 就终止遍历
if (sum + candidates[i] > target) break;
sum += candidates[i];
path.add(candidates[i]);
backstacking(candidates, target, i);
//回溯
path.removeLast();
sum -= candidates[i];
}
三、解决问题
解决:剪枝优化操作,可以放在终止条件中,这样不论如何都可以遍历完for循环的所有元素。
修改后代码如下,提交代码通过。