LeetCode 90. Subsets II 原创Java参考解答
问题描述
https://leetcode.com/problems/subsets-ii/
Given a collection of integers that might contain duplicates, nums, return all possible subsets.
Note: The solution set must not contain duplicate subsets.
For example,
If nums = [1,2,2]
, a solution is:
[ [2], [1], [1,2,2], [2,2], [1,2], [] ]
解题思路
这道题是Subsets题目的Follow up加强版题目。求一个数组的所有子集数组。原数组可能有重复元素。
和Subsets题目基本上一样的思路和解法,由题目“求所有子集”联想到DFS深度优先搜索。考点仍旧是递归,只是这道题需要去重。
我们不能求完所有子集后再去重,因为那样时间复杂度会太高,为O(2N * N),N为数组元素数量。我们需要在递归找子集过程中就处理重复的情况。
参考代码
解答代码和Subsets代码基本一样,只是加入了去重的手段。我们的去重手段就是对于相同的数字只用计算出前面一个的子集。比如,对于[1, 1],我们只用求出前面一个1的所有子集。
- 排序数组使数值一样的元素相邻地排在一起
- 如果某位置元素和前一位置数值相同了,即nums[i] = nums[i – 1],那么就跳过该位置。通过 i > startIndex 来判断当前 i 是否是当前子集的出发位置还是后面位置。
public class Solution { public List<List<Integer>> subsetsWithDup(int[] nums) { List<List<Integer>> results = new ArrayList<>(); if (nums == null || nums.length == 0) { return results; } Arrays.sort(nums); List<Integer> subset = new ArrayList<>(); dfsHelper(nums, 0, results, subset); return results; } private void dfsHelper(int[] nums, int startIndex, List<List<Integer>> results, List<Integer> subset) { // deep copy and add to result results.add(new ArrayList<>(subset)); for (int i = startIndex; i < nums.length; i++) { if (i != 0 && nums[i] == nums[i - 1] && i > startIndex) { continue; } subset.add(nums[i]); dfsHelper(nums, i + 1, results, subset); subset.remove(subset.size() - 1); } } }