Leetcode OJ 78 Subsets [medium]

来源:互联网 发布:windows git 配置文件 编辑:程序博客网 时间:2024/06/04 19:13

Leetcode OJ 78 Subsets [medium]

题目描述:

Given a set of distinctintegers, nums, return all possible subsets.

Note: The solution setmust not contain duplicate subsets.

For example,
If nums = [1,2,3], a solution is:

[

  [3],

  [1],

  [2],

  [1,2,3],

  [1,3],

  [2,3],

  [1,2],

  []

]

 

题目理解:

    给定一个整数数字的集合,没有重复的元素,返回所有的子集,不能出现重复的子集。

测试用例:

    功能测试:包含2个、3个、k个数字的集合;

    边界测试:空子集;只有1个数字的集合;

分析:

方法一:DFS深度优先搜索:

    1.  

    2.   搜索的顺序是:[]—[1]—[1,2]—[1,2,3]—[1,3]—[2]--[2,3]--[3]

    3.   DFS的过程是:

       1) 添加当前的结果;

       2) 使用for循环遍历其他节点(为了去重,从当前节点之后的节点开始遍历)

              添加当前节点;

              对当前节点调用递归函数;

             删除当前节点

    4.   131 Palindrome Partitioning / 46.Permutations / 77 Combination / 都可以用DFS深度优先搜索解决

实现:

class Solution {    public List<List<Integer>>subsets(int[] nums) {        List<List<Integer>>result = new ArrayList();        List<Integer> temp = new ArrayList();        subsetDFS(result,temp,nums,0);        return result;    }    static public void subsetDFS(List<List<Integer>> result,List<Integer> temp,int[]nums,int start){        result.add(new ArrayList<>(temp));        for(int i =start;i < nums.length;i++){            temp.add(nums[i]);            subsetDFS(result,temp,nums,i+1);            temp.remove(temp.size()-1);        }    }}

注意:

result.add(newArrayList<>(temp));不能写成  result.add(temp);

方法二:位操作

1.   对于数组[1,2,3],可以用一个下标0和1表示是否选择该数字,0表示未选择,1表示选中,那么每一组3个0和1的组合表示一种选择,3位共有8种选择,分别是:
000 对应[]
001 对应[3]
010 对应[2]
011 对应[2,3]
100 …
101
110
111
那么上面为1的位表示数组中该位被选中。
那么只需要遍历0到1<< length中的数,判断每一个数中有那几位为1,为1的那几位即会构成一个子集中的一个元素。

方法三:递归

1.   仔细分析,我们发现包含n个元素的集合的子集有以下三个部分组成:

2.   第一部分,该集合前n-1个元素组成的集合的子集;

3.   第二部分,该集合中最后一个元素构成的一个子集合;

4.   第三部分,对该集合前n-1个元素组成的集合的子集,每一个都添加最后一个元素;

5.   注意,对于返回的集合的全部子集包括一个空子集!

 

 

原创粉丝点击