回溯算法 + 剪枝java
import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Deque; import java.util.List; public class Solution { public List<List<Integer>> combinationSum(int[] candidates, int target) { List<List<Integer>> res = new ArrayList<>(); int len = candidates.length; // 排序是爲了提早終止搜索 Arrays.sort(candidates); dfs(candidates, len, target, 0, new ArrayDeque<>(), res); return res; } /** * [@param](https://my.oschina.net/u/2303379) candidates 數組輸入 * [@param](https://my.oschina.net/u/2303379) len 輸入數組的長度,冗餘變量 * [@param](https://my.oschina.net/u/2303379) residue 剩餘數值 * [@param](https://my.oschina.net/u/2303379) begin 本輪搜索的起點下標 * [@param](https://my.oschina.net/u/2303379) path 從根結點到任意結點的路徑 * @param res 結果集變量 */ private void dfs(int[] candidates, int len, int residue, int begin, Deque<Integer> path, List<List<Integer>> res) { if (residue == 0) { // 因爲 path 全局只使用一份,到葉子結點的時候須要作一個拷貝 res.add(new ArrayList<>(path)); return; } for (int i = begin; i < len; i++) { // 在數組有序的前提下,剪枝 if (residue - candidates[i] < 0) { break; } path.addLast(candidates[i]); dfs(candidates, len, residue - candidates[i], i, path, res); path.removeLast(); } } }