/* * 题目:给你一个整数数组nums ,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。解集不能包含重复的子集。返回的解集中,子集可以按任意顺序排列。 * 算法:组合问题可以转化为树形结构,题目中的“使用过”在树形结构上是有两个维度的,一个维度是同一树枝上使用过,一个维度是同一树层上使用过。我们要去重的是同一树层上的“使用过“,同一树枝上的都是一个组合里的元素,不用去重。 * * */ package cn.wanggeng.back; import java.util.ArrayList; import java.util.List; public class SubsetsWithDup { public List<List<Integer>> subsetsWithDup(int[] nums) { List<List<Integer>> res = new ArrayList<List<Integer>>(); List<Integer> path = new ArrayList<Integer>(); boolean[] visited = new boolean[nums.length]; //进行排序,使得相同的元素相邻,便于去重 Arrays.sort(nums); back(res, path, nums, 0, visited); return res; } public void back(List<List<Integer>> res, List<Integer> path, int[] nums, int index, boolean[] visited){ res.add(new ArrayList(path)); for(int i = index; i < nums.length; i++){ if(i > index && nums[i] == nums[i - 1] && ! visited[i - 1]){ continue; } visited[i] = true; path.add(nums[i]); back(res, path, nums, i + 1, visited); //回朔 visited[i] = false; path.remove(path.size() - 1); } } }