幂集。编写一种方法,返回某集合的所有子集。集合中不包含重复的元素。
说明:解集不能包含重复的子集。
示例:
输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/power-set-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
package BackTrack;
import java.util.ArrayList;
import java.util.List;
public class PowerSetLCCI {
public static void main(String[] args) {
int[] test = {1,2,6};
for(List<Integer> element:method2(test)){
System.out.println(element);
}
}
//法一:非递归解决
public static List<List<Integer>> method1(int[] nums){
List<List<Integer>> res = new ArrayList<>();
res.add(new ArrayList<>(){});
for(int num:nums){
//(int i=0;i<res.size();i++)这种写法会报错,因为res.size()会不断发生变化
for(int i = 0, j = res.size(); i < j; i++){
List<Integer> list = new ArrayList<>(res.get(i));
list.add(num);
res.add(list);
}
}
return res;
}
//法二:递归解决
public static List<List<Integer>> method2(int[] nums){
List<List<Integer>> res = new ArrayList<>(1 << nums.length);
res.add(new ArrayList<>());
recursion(nums, 0, res);
return res;
}
public static void recursion(int[] nums, int index, List<List<Integer>> res) {
//数组中的元素都访问完了,直接return
if (index >= nums.length)
return;
int size = res.size();
for (int j = 0; j < size; j++) {
List<Integer> list = new ArrayList<>(res.get(j));
//然后在新的子集后面追加一个值
list.add(nums[index]);
res.add(list);
}
//递归下一个元素
recursion(nums, index + 1, res);
}
//回溯
public List<List<Integer>> subsets(int[] nums) {
//存放结果
List<List<Integer>> list = new ArrayList<>();
//开始递归
backtrack(list, new ArrayList<>(), nums, 0);
return list;
}
private void backtrack(List<List<Integer>> list, List<Integer> tempList, int[] nums, int start) {
//走过的所有路径都是子集的一部分,所以都要加入到集合中
list.add(new ArrayList<>(tempList));
//从第start哥元素开始
for (int i = start; i < nums.length; i++) {
//做出选择
tempList.add(nums[i]);
//递归
backtrack(list, tempList, nums, i + 1);
//撤销选择
tempList.remove(tempList.size() - 1);
}
}
}