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);
}
}
}