题目
Given a set of distinct integers, nums, return all possible subsets.
Note:
Elements in a subset must be in non-descending order.
The solution set must 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],
[]
]
题目大意:找出一个集合中的所有子集,包括空集和全集。注意:子集中的元素要按照升序进行排序。
思路
此题在《剑指Offer》中做过,http://blog.csdn.net/u010412719/article/details/49005427
思路为:开辟一个与数组相同长度的标志数组arr,里面的元素非0即1,当元素为1时,表示数组nums中的相同的位参与了组合。当arr中的元素模拟二进制数加1操作,当binaryArr中的元素从全0到全1后,就得到了所有的组合。
由于需要保存结果,因此,用带容器像java这样的语言方便实现一点。无论选择何种语言,思路都是上面的思路。
java实现代码如下:
public class Solution {
//模拟二进制加1
public boolean increment(int []arr){
int len=arr.length;
arr[len-1]++;//最低位加1
for(int i=len-1;i>=0;i--){
if(arr[i]>=2){
if(i==0){//最高位产生了进位,则已经变为了全一,结束
return false;
}
else{//
arr[i]-=2;
arr[i-1]++;
}
}
}
return true;
}
public List<List<Integer>> subsets(int[] nums) {
if(nums==null||nums.length<1){
return null;
}
//先进行排序
Arrays.sort(nums);
//开辟一个与nums长度相同的标志数组,并初始化为零
int len=nums.length;
int arr[]=new int[len];
for(int i=0;i<len;i++){
arr[i]=0;
}
//定义一个List来保存结果
List<List<Integer>> resultList=new ArrayList<List<Integer>>();
resultList.add(new ArrayList<Integer>());//将空集加入
while(increment(arr)){//模拟二进制加一
List<Integer> list=new ArrayList<Integer>();//
for(int i=0;i<len;i++){
if(arr[i]==1){//arr中标志位1时,nums的相应元素参与了组合
list.add(nums[i]);
}
}
resultList.add(list);
}
return resultList;
}
}
AC结果如下:
出现的问题
1、没有考虑排序的问题
解决方法:将数组先进行排序然后进行后面的操作。