这题就是不能重复取的题,首先要做的事情就是对数组进行排序。
- 需要额外提供一个数组
boolean[] visited用以判断前面节点是否已获取,主要用于去重操作。 没有步骤
#1的判断,那么当输入为[1,1,2], target=3时则会返回[1,2]、[1,2]重复元素,这就体现boolean[] visited的作用,用以剪枝去重。它的意思是,当两数相等时,前面重复的元素已经取得了,本轮就跳过。public class No_82_combinationSum2 {public static void main(String[] args) {No_82_combinationSum2 go = new No_82_combinationSum2();int[] nums = {1, 1, 2};int target = 3;List<List<Integer>> lists = go.combinationSum2(nums, target);for (List<Integer> list : lists) {System.out.println(list);}}List<List<Integer>> res;public List<List<Integer>> combinationSum2(int[] candidates, int target) {if (candidates == null || candidates.length == 0 || target < 1) return new ArrayList<>();res = new ArrayList<>();Arrays.sort(candidates);boolean[] visited = new boolean[candidates.length];List<Integer> path = new ArrayList<>();backTracking(candidates, 0, target, path, visited);return res;}private void backTracking(int[] nums, int pos, int target, List<Integer> path, boolean[] visited) {if (target < 0) return;if (target == 0) {// collectres.add(new ArrayList<>(path));return;}for (int i = pos; i < nums.length; i++) {System.out.println(getBlackSpace(pos) + "当前节点: " + nums[i]);// #1// if (i > 0 && !visited[i - 1] && nums[i - 1] == nums[i]) continue;path.add(nums[i]);visited[i] = true;// 剪枝backTracking(nums, i + 1, target - nums[i], path, visited);path.remove(path.size() - 1);visited[i] = false;}}private String getBlackSpace(int n) {StringBuilder sb = new StringBuilder();for (int i = 0; i < 2 * n; i++) {sb.append(" ");}return sb.toString();}}
