image.png

解决思路

回溯算法 + 剪枝

image.png
image.png
image.png
image.png

  1. public List<List<Integer>> combinationSum(int[] candidates, int target) {
  2. List<List<Integer>> res = new ArrayList<>();
  3. int len = candidates.length;
  4. // 排序是为了提前终止搜索
  5. Arrays.sort(candidates);
  6. dfs(candidates,len,target,0,new ArrayDeque<>(),res);
  7. return res;
  8. }
  9. /**
  10. * @param candidates 数组输入
  11. * @param len 输入数组的长度,冗余变量
  12. * @param residue 剩余数值
  13. * @param begin 本轮搜索的起点下标
  14. * @param path 从根结点到任意结点的路径
  15. * @param res 结果集变量
  16. */
  17. private void dfs(int[] candidates,int len, int residue,int begin, Deque<Integer> path, List<List<Integer>> res){
  18. if (residue == 0){
  19. // 由于 path 全局只使用一份,到叶子结点的时候需要做一个拷贝
  20. res.add(new ArrayList<>(path));
  21. return;
  22. }
  23. for (int i = begin;i < len;i++){
  24. // 在数组有序的前提下,剪枝
  25. if (residue - candidates[i] < 0) {
  26. break;
  27. }
  28. path.addLast(candidates[i]);
  29. dfs(candidates, len, residue - candidates[i], i, path, res);
  30. path.removeLast();
  31. }
  32. }