Leetcode 78 Subset:
Given a set of distinct integers, nums, return all possible subsets (the power set).
Note: The solution set must not contain duplicate subsets.
Example:
如果S=[1,2,3], 给出的解集应为:
[↵ [3],↵ [1],↵ [2],↵ [1,2,3],↵ [1,3],↵ [2,3],↵ [1,2],↵ []↵]
需要注意的坑:
1. "组合"和"排列"不一样,对于例子中给出的数组,两个数的排列有12, 13, 21, 23, 31, 32,但是组合只有12, 13, 23,即每次回溯的时候,可以以当前的start节点开始,不用从零开始。另外,组合既然是从start开始的,就不需要一个book数组来记录这个词是否被用过了。
2. 每次递归后,需要将当前循环加入的元素remove掉,否则将会影响后续的结果。
class Solution {
public List<List<Integer>> res = new ArrayList<List<Integer>>();
public List<List<Integer>> subsets(int[] nums) {
if (nums == null || nums.length == 0) {
return res;
}
Arrays.sort(nums);
dfs(nums, 0, new ArrayList<Integer>());
return res;
}
public void dfs(int[] nums, int index, ArrayList<Integer> list) {
ArrayList<Integer> temp = new ArrayList<>(list);
res.add(temp);
for (int i = index; i < nums.length; i++) {
temp.add(nums[i]);
dfs(nums, i + 1, temp);
temp.remove(temp.size() - 1);
}
}
}
Leetcode 90 Subset iii:
Given a collection of integers that might contain duplicates, nums, return all possible subsets (the power set).
Note: The solution set must not contain duplicate subsets.
Example:
如果S =[1,2,2], 给出的解集应该是:
[↵ [2],↵ [1],↵ [1,2,2],↵ [2,2],↵ [1,2],↵ []↵]
思路:回溯法/深度优先遍历,对数组排序,保证升序;判断前后是否重复(代码中的while () {}),遇到相同的数字直接跳下一个,忽略这个重复的,保存无重复子集。
class Solution {
public ArrayList<List<Integer>> res = new ArrayList<List<Integer>>();
public List<List<Integer>> subsetsWithDup(int[] num) {
if (num == null || num.length == 0) {
return null;
}
Arrays.sort(num);
dfs(num, new ArrayList<Integer>(), 0);
return res;
}
public void dfs(int[] nums, List<Integer> list, int index) {
List<Integer> temp = new ArrayList<>(list);
res.add(temp);
for (int i = index; i < nums.length; i++) {
temp.add(nums[i]);
dfs(nums, temp, i + 1);
while (i < nums.length - 1 && nums[i + 1] == nums[i]) {
i++;
}
temp.remove(temp.size() - 1);
}
}
}