0
点赞
收藏
分享

微信扫一扫

JAVA练习173-幂集

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

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

示例:
 输入: nums = [1,2,3]
 输出:
[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]

分析:

方法1:DFS+回溯

拿 [1,2,3] 举例,寻找它的子集过程可以看做:

  • [ ]             空集开始
  • [1]            添加 1
  • [1,2]         添加 2
  • [1,2,3]      添加 3,遍历到头
  • [1,3]         回溯到 [1],添加 3,遍历到头
  • [2]            回溯到 [ ],添加 2
  • [2,3]         添加 3,遍历到头
  • [3]            回溯到 [ ],添加 3

我们可以用深度遍历(DFS)来模拟这个过程,递归参数为数组索引,递归终止条件就是遍历到头,每一次递归我们就添加一次子集,子集添加当前元素,回溯时,就将当前元素删除。

时间复杂度:O(2^n)          假设数组是个二进制数,里面的数字只有选中和未选中状态即 1 和 0,那么它的子集个数就是这个二进制数,即 2^n
空间复杂度:O(2^n) 

class Solution {

    //结果集合
    List<List<Integer>> res = new ArrayList<>();
    //子集
    List<Integer> list = new ArrayList<>();
    //数组
    int[] nums;

    public List<List<Integer>> subsets(int[] nums) {
        this.nums = nums;
        dfs(0);
        return res;
    }

    public void dfs(int n){
        //添加子集
        res.add(new ArrayList(list));
        //遍历
        for(int i = n; i < nums.length; ++i){
            //添加该元素
            list.add(nums[i]);
            //深度遍历
            dfs(i+1);
            //删除该元素
            list.remove(list.size()-1);
        }
    }
}

方法2:动态规划

依然拿 [1,2,3] 举例,寻找它的子集过程可以看做:

  • [ ]                                                                       没有元素
  • [ ]  [1]                                                                 添加第一个元素
  • [ ]  [1]  [2]  [1,2]                                                  添加第二个元素
  • [ ]  [1]  [2]  [1,2]  [3]  [1,3]  [2,3]  [1,2,3]              添加第三个元素

 每一次添加就相当于在前面子集的情况下添加自己的元素,转移方程不好表示,就不写了。

时间复杂度:O(2^n)          
空间复杂度:O(2^n) 

class Solution {

    //结果集合
    List<List<Integer>> res = new ArrayList<>();
    //数组
    int[] nums;

    public List<List<Integer>> subsets(int[] nums) {
        this.nums = nums;
        //添加空集
        res.add(new ArrayList<>());
        recur(0);
        return res;
    }

    public void recur(int n){
        //到头
        if(n == nums.length){
            return;
        }
        //结果集合大小
        int size = res.size();
        //遍历,添加元素
        for(int i = 0; i < size; ++i){
            //复制子集
            List<Integer> list = new ArrayList(res.get(i));
            //添加元素
            list.add(nums[n]);
            //添加到结果集
            res.add(list);
        }
        //递归
        recur(n+1);
    }
}

题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/power-set-lcci

举报

相关推荐

0 条评论