子集
题目
给定一个含不同整数的集合,返回其所有的子集
注意事项
子集中的元素排列必须是非降序的,解集必须不包含重复的子集样例
如果 S = [1,2,3],有如下的解:
挑战
你可以同时用递归与非递归的方式解决么?
题解
1.递归法
先对数组排序,然后回溯递归。下图是以样例画的很粗糙的递归堆栈图,对着代码推算一遍就明白了。
class Solution {
/**
* @param S: A set of numbers.
* @return: A list of lists. All valid subsets.
*/
public ArrayList<ArrayList<Integer>> subsets(int[] nums) {
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> list = new ArrayList<Integer>();
Arrays.sort(nums);
subsetsHelper(result, list, nums, 0);
return result;
}
private void subsetsHelper(ArrayList<ArrayList<Integer>> result,
ArrayList<Integer> list, int[] nums, int pos)
{
result.add(new ArrayList<Integer>(list));
for (int i=pos;i<nums.length;i++)
{
list.add(nums[i]);
subsetsHelper(result,list,nums,i+1);
list.remove(list.size()-1);
}
}
}
2.非递归法
我们还是以[1,2,3]为例进行如下分析:
0x000->[];
0x001->[1];
0x010->[2];
…
0x111->[1,2,3];
也就是每一个子集都对应[0,2^n-1]中的一个二进制。
class Solution {
/**
* @param S: A set of numbers.
* @return: A list of lists. All valid subsets.
*/
public ArrayList<ArrayList<Integer>> subsets(int[] nums) {
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
int n = nums.length;
Arrays.sort(nums);
for (int i=0;i<(1<<n);i++)
{
ArrayList<Integer> list = new ArrayList<Integer>();
for (int j=0;j<n;j++)
{
if ((i&(1<<j)) != 0)
{
list.add(nums[j]);
}
}
result.add(list);
}
return result;
}
}
Last Update 2016.9.24