【Important】78.子集
阿新 • • 發佈:2021-01-10
78.子集
給你一個整數陣列 nums ,返回該陣列所有可能的子集(冪集)。解集不能包含重複的子集。
示例 1:
輸入:nums = [1,2,3]
輸出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
示例 2:
輸入:nums = [0]
輸出:[[],[0]]
提示:
1 <= nums.length <= 10
-10 <= nums[i] <= 10
該題目為非常標準的dfs問題,用於瞭解最基本的dfs演算法
演算法核心:每個數字有可能或者不出現在解中 以該核心衍生出四種不同的演算法
1、標準dfs
這裡給出dfs演算法模板 同時會記錄與演算法專欄-模板中
ArrayList<int> t; ArrayList<ArrayList<int>> res; public void dfs(int pos, int length) { if (pos == length) { //如果當前指標超過了陣列索引 則為一個完整的解 返回 // res.add(new ArrayList<>(t)); return; } // 考慮選擇當前位置 t.add(nums[pos]); dfs(pos + 1, length); // 當前位置出現在解中 t.remove(t.size() - 1); // 考慮不選擇當前位置 dfs(pos + 1, length); //當前位置不出現在解中 }
因此 本題標準解為
class Solution { ArrayList<List<Integer>> res = new ArrayList<List<Integer>>(); ArrayList<Integer> temp = new ArrayList<>(); public List<List<Integer>> subsets(int[] nums) { int n = nums.length; dfs(nums, 0, n); return res; } public void dfs (int[] nums, int pos, int len){ if (pos == len){ res.add(new ArrayList<>(temp)); return; } temp.add(nums[pos]); dfs(nums, pos + 1, len); temp.remove(temp.size() - 1); dfs(nums, pos+1, len); } }
2、樹的中序遍歷
1的題解本質思想其實就是一顆二叉樹,數字左右節點分別代表取 或者 不取 在當前位置上的值,所有葉子節點構成了解集。
因此在做dfs的題時,將抽象的概念具體化成樹有助於理解題目
3、位運算
本題的核心的另一種解讀:將每個數字出現與否轉換為位上是否為1
class Solution {
public List<List<Integer>> subsets(int[] nums) {
ArrayList<List<Integer>> res = new ArrayList<List<Integer>>();
List<Integer> temp = new ArrayList<>();
int n = nums.length;
for (int mask = 0; mask < (1 << n); mask++){
temp.clear();
for (int i = 0; i < n;i++){
if (( (1 << i) & mask ) != 0) temp.add(nums[i]);
}
res.add(new ArrayList(temp));
}
return res;
}
}
4、遍歷新增法
需要一些技巧才能想出來的解法,本質上是從核心部分推出來的解法
class Solution {
public List<List<Integer>> subsets(int[] nums) {
ArrayList<List<Integer>> res = new ArrayList<List<Integer>>();
List<Integer> temp = new ArrayList<>();
res.add(new ArrayList<Integer>());
int n = nums.length;
for (int i = 0; i < n; i++){
int value = nums[i];
int currentSize = res.size();
for (int j = 0; j < currentSize;j++){
List<Integer> currentList = new ArrayList(res.get(j));
currentList.add(value);
res.add(currentList);
}
}
return res;
}
}