幂集。编写一种方法,返回某集合的所有子集。集合中不包含重复的元素。

    说明:解集不能包含重复的子集。

    示例:

    输入: 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
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    1. package BackTrack;
    2. import java.util.ArrayList;
    3. import java.util.List;
    4. public class PowerSetLCCI {
    5. public static void main(String[] args) {
    6. int[] test = {1,2,6};
    7. for(List<Integer> element:method2(test)){
    8. System.out.println(element);
    9. }
    10. }
    11. //法一:非递归解决
    12. public static List<List<Integer>> method1(int[] nums){
    13. List<List<Integer>> res = new ArrayList<>();
    14. res.add(new ArrayList<>(){});
    15. for(int num:nums){
    16. //(int i=0;i<res.size();i++)这种写法会报错,因为res.size()会不断发生变化
    17. for(int i = 0, j = res.size(); i < j; i++){
    18. List<Integer> list = new ArrayList<>(res.get(i));
    19. list.add(num);
    20. res.add(list);
    21. }
    22. }
    23. return res;
    24. }
    25. //法二:递归解决
    26. public static List<List<Integer>> method2(int[] nums){
    27. List<List<Integer>> res = new ArrayList<>(1 << nums.length);
    28. res.add(new ArrayList<>());
    29. recursion(nums, 0, res);
    30. return res;
    31. }
    32. public static void recursion(int[] nums, int index, List<List<Integer>> res) {
    33. //数组中的元素都访问完了,直接return
    34. if (index >= nums.length)
    35. return;
    36. int size = res.size();
    37. for (int j = 0; j < size; j++) {
    38. List<Integer> list = new ArrayList<>(res.get(j));
    39. //然后在新的子集后面追加一个值
    40. list.add(nums[index]);
    41. res.add(list);
    42. }
    43. //递归下一个元素
    44. recursion(nums, index + 1, res);
    45. }
    46. //回溯
    47. public List<List<Integer>> subsets(int[] nums) {
    48. //存放结果
    49. List<List<Integer>> list = new ArrayList<>();
    50. //开始递归
    51. backtrack(list, new ArrayList<>(), nums, 0);
    52. return list;
    53. }
    54. private void backtrack(List<List<Integer>> list, List<Integer> tempList, int[] nums, int start) {
    55. //走过的所有路径都是子集的一部分,所以都要加入到集合中
    56. list.add(new ArrayList<>(tempList));
    57. //从第start哥元素开始
    58. for (int i = start; i < nums.length; i++) {
    59. //做出选择
    60. tempList.add(nums[i]);
    61. //递归
    62. backtrack(list, tempList, nums, i + 1);
    63. //撤销选择
    64. tempList.remove(tempList.size() - 1);
    65. }
    66. }
    67. }