题目
子集
给定一个含不同整数的集合,返回其所有的子集
样例
如果 S = [1,2,3]
,有如下的解:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
注意
子集中的元素排列必须是非降序的,解集必须不包含重复的子集
挑战
Java Code
Java Code
Python Code
View Code
Python Code
你可以同时用递归与非递归的方式解决么?
解题
根据上面求排列的思想很类似,还是深度优先遍历。由于输出每个子集需要升序,所以要先对数组进行排序。求出所以的子集,也就是求出所以的组合方式 + 空集
问题转化为求组合方式的问题
参考链接不仅要考虑起始位置,还需要考虑长度,这样才是组合 C(n,k),由于我只想到要考虑起始位置,而长度问题在程序中增加,一直没有解决问题
核心程序
public void helper(int[] nums,int start,int len, ArrayList<Integer> list,ArrayList<ArrayList<Integer>> res){ if( list.size() == len){ res.add(new ArrayList<Integer>(list)); return; } for(int i=start;i< nums.length;i++){ if(list.contains(nums[i])){ continue; } list.add(nums[i]); helper(nums,i+1,len,list,res); list.remove(list.size()-1); } }
class Solution { /** * @param S: A set of numbers. * @return: A list of lists. All valid subsets. */ public ArrayList<ArrayList<Integer>> subsets(int[] nums) { // write your code here ArrayList<Integer> list = new ArrayList<Integer>(); ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>(); if(nums == null || nums.length ==0) return res; Arrays.sort(nums); res.add(list); for(int len = 1;len<= nums.length;len++){ helper(nums,0,len,list,res); } return res; } public void helper(int[] nums,int start,int len, ArrayList<Integer> list,ArrayList<ArrayList<Integer>> res){ if( list.size() == len){ res.add(new ArrayList<Integer>(list)); return; } for(int i=start;i< nums.length;i++){ if(list.contains(nums[i])){ continue; } list.add(nums[i]); helper(nums,i+1,len,list,res); list.remove(list.size()-1); } } }
九章中程序进行了优化,长度不考虑,递归一次list的值都是子集的一个元素
class Solution { /** * @param S: A set of numbers. * @return: A list of lists. All valid subsets. */ public ArrayList<ArrayList<Integer>> subsets(int[] nums) { // write your code here ArrayList<Integer> list = new ArrayList<Integer>(); ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>(); if(nums == null || nums.length ==0) return res; Arrays.sort(nums); helper(nums,0,list,res); return res; } public void helper(int[] nums,int start, ArrayList<Integer> list,ArrayList<ArrayList<Integer>> res){ res.add(new ArrayList<Integer>(list)); for(int i=start;i< nums.length;i++){ if(list.contains(nums[i])){ continue; } list.add(nums[i]); helper(nums,i+1,list,res); list.remove(list.size()-1); } } }
class Solution: """ @param S: The set of numbers. @return: A list of lists. See example. """ def subsets(self, S): def dfs(depth, start, valuelist): res.append(valuelist) if depth == len(S): return for i in range(start, len(S)): dfs(depth+1, i+1, valuelist+[S[i]]) S.sort() res = [] dfs(0, 0, []) return res
根据位运算进行求解
// 1 << n is 2^n // each subset equals to an binary integer between 0 .. 2^n - 1 // 0 -> 000 -> [] // 1 -> 001 -> [1] // 2 -> 010 -> [2] // .. // 7 -> 111 -> [1,2,3]
下面是我自己实现
class Solution { /** * @param S: A set of numbers. * @return: A list of lists. All valid subsets. */ public ArrayList<ArrayList<Integer>> subsets(int[] nums) { // write your code here int len = nums.length; ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>(); if(nums == null || len==0) return res; Arrays.sort(nums); // 1 << n is 2^n // each subset equals to an binary integer between 0 .. 2^n - 1 // 0 -> 000 -> [] // 1 -> 001 -> [1] // 2 -> 010 -> [2] // .. // 7 -> 111 -> [1,2,3] for(int i=0;i< 1<<len ;i++){ ArrayList<Integer> list = new ArrayList<Integer>(); // 检测哪一位是 1 int n = i; for(int j=0;j< len;j++){ if(n%2==1) list.add(nums[j]); n=n/2; } res.add(list); } return res; } }
九章中判断第几位是1的程序如下:
for (int i = 0; i < (1 << n); i++) { ArrayList<Integer> subset = new ArrayList<Integer>(); for (int j = 0; j < n; j++) { // check whether the jth digit in i's binary representation is 1 if ((i & (1 << j)) != 0) { subset.add(nums[j]); } } result.add(subset); }
是懂非懂,好像这样也可以判断第几位是1
class Solution: """ @param S: The set of numbers. @return: A list of lists. See example. """ def subsets(self, nums): # write your code here res = [] size = len(nums) nums.sort() if nums == None or size == 0: return res for i in range(1<<size): lst=[] n = i for j in range(size): if n%2==1: lst.append(nums[j]) n/=2 res.append(lst) return res