參考了以下的人終於搞懂了點
78 子集 給定一組不含重複元素的整數數組 nums,返回該數組所有可能的子集(冪集)。 說明:解集不能包含重複的子集。 Given a set of distinct integers, nums, return all possible subsets (the power set). Note: The solution set must not contain duplicate subsets.
/*思路1 * Backtracking+dfs * 回溯+深度優先搜索 * 如果要理解,看到一個解釋,也可以當作:存在和不存在。 * 外層循環逐一往中間集合 temp 中加入元素 nums[i],使這個元素處於存在狀態 * 開始遞歸,遞歸中攜帶加入新元素的 temp,並且下一次循環的起始是 i 元素的下一個,因而遞歸中更新 i 值爲 i + 1 * 將這個從中間集合 temp 中移除,使該元素處於不存在狀態 * */
public static List<List<Integer>> subsets(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> res = new ArrayList<>();
List<Integer> temp = new ArrayList<>();
dfs(res, temp, nums, 0);
return res;
}
/* * 再具體點 * 形如[1,2,3]得到 * [[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]] * 假設某一步 temp=》 tempList.add(nums[i])=>[1] * 在進行dfs的時候是[1]add下一層=》[1,2]=>再下一層dfs->[1,2,3],結束後往上回溯remove 3 =>[1,2] * 繼續回溯會變爲remove 2 =>[1] 最外層remove 1 =》[] * 最最外層循環結束,i++,從num[1]=2開始=temp=>[2] * */
private static void dfs(List<List<Integer>> list, List<Integer> tempList, int[] nums, int start) {
list.add(new ArrayList<>(tempList));
for (int i = start; i < nums.length; i++) {
tempList.add(nums[i]);
dfs(list, tempList, nums, i + 1);
tempList.remove(tempList.size() - 1);
}
}
附帶循環的思路
package Array.Medium;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/*78 子集
* 給定一組不含重複元素的整數數組 nums,返回該數組所有可能的子集(冪集)。
* 說明:解集不能包含重複的子集。
* Given a set of distinct integers, nums, return all possible subsets (the power set).
* Note: The solution set must not contain duplicate subsets.
* */
public class Subsets {
/*思路1
* Backtracking+dfs
* 回溯+深度優先搜索
* 如果要理解,看到一個解釋,也可以當作:存在和不存在。
* 外層循環逐一往中間集合 temp 中加入元素 nums[i],使這個元素處於存在狀態
* 開始遞歸,遞歸中攜帶加入新元素的 temp,並且下一次循環的起始是 i 元素的下一個,因而遞歸中更新 i 值爲 i + 1
* 將這個從中間集合 temp 中移除,使該元素處於不存在狀態
* */
public static List<List<Integer>> subsets1(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> res = new ArrayList<>();
List<Integer> temp = new ArrayList<>();
dfs(res, temp, nums, 0);
return res;
}
/* * 再具體點
* 形如[1,2,3]得到
* [[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]]
* 假設某一步 temp=》 tempList.add(nums[i])=>[1]
* 在進行dfs的時候是[1]add下一層=》[1,2]=>再下一層dfs->[1,2,3],結束後往上回溯remove 3 =>[1,2]
* 繼續回溯會變爲remove 2 =>[1] 最外層remove 1 =》[]
* 最最外層循環結束,i++,從num[1]=2開始=temp=>[2]
* */
private static void dfs(List<List<Integer>> list, List<Integer> tempList, int[] nums, int start) {
list.add(new ArrayList<>(tempList));
for (int i = start; i < nums.length; i++) {
tempList.add(nums[i]);
dfs(list, tempList, nums, i + 1);
tempList.remove(tempList.size() - 1);
}
}
/*思路3
* 選和不選+二進制
* [ 1 , 2 , 3 ]
* f f f []
* t f f [1]
* t t f [1,2]
* ...類推
* */
/*思路2
* 遍歷
* 出現新的,就把新的添加到上一層子集的後面
* 詳解
* res的size是遞增的
* 外層遍歷每個nums的元素
* 內層遍歷res的元素,被外層當前元素add進temp再add進res即可
* */
public static List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
res.add(new ArrayList<>());
for (int num : nums) { // ①從數組中取出每個元素
int size = res.size();
for (int i = 0; i < size; i++) {
List<Integer> temp = new ArrayList<>(res.get(i)); // ②逐一取出中間結果集
System.out.println(res.get(i));
temp.add(num); // ③將 num 放入中間結果集
res.add(temp); // ④加入到結果集中
}
}
return res;
}
public static void main(String[] args) {
int[] num = {1, 2, 3};
System.out.println(subsets(num));
}
}