您的位置:首页 > 其它

集合的子集

2016-03-23 22:16 330 查看
请编写一个方法,返回某集合的所有非空子集。
给定一个int数组A和数组的大小int
n,请返回A的所有非空子集。保证A的元素个数小于等于20,且元素互异。各子集内部从大到小排序,子集之间字典逆序排序,见样例。
[123,456,789]
子集:{[789,456,123],[789,456],[789,123],[789],[456 123],[456],[123]}

集合的每个元素都可以通过bit来表示
1表示有这个数 0表示没有这个数
子集可以通过二进制的方式表示
1 1 1 7 789,456,123
1 1 0 6 789,456
1 0 1 5 789,123
1 0 0 4 789
0 1 1 3 456 123
0 1 0 2 456
0 0 1 1 123
0 0 0 0 空集
所以这个问题可以转化为:怎样可以从大到小的遍历二进制?
int i=(1<<n)-1
for(int i=i;i>=0;i-—){
for(int j=n-1;j>=0;j-—){
if((i&1<<j)>0){
集合里面有这个数 加入进去
}}
}
完整代码:
import java.util.*;

public class Subset {
public ArrayList<ArrayList<Integer>> getSubsets(int[] A, int n) {
ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
if(n==0){//合法性检测
return res;
}
Arrays.sort(A);//排序从小到大
swap(A,0,n-1);//排序从大到小
int start = (1<<n)-1;
for(int i=start;i>0;i--){//遍历二进制的方法
ArrayList<Integer> item = new ArrayList<Integer>();
for(int j=n-1;j>=0;j--){//保证从大到小序列间有序
if((i&(1<<j))>0){
item.add(A[n-1-j]);
}
}
res.add(item);

}
return res;
}
public void swap(int[] A,int start,int end){
while(start<end){
if(A[start]<A[end]){
A[start] = A[start]^A[end];
A[end] = A[start]^A[end];
A[start] = A[start]^A[end];
}
start++;
end--;
}

}
}
题目链接:http://www.nowcoder.com/practice/1f2700e2b1904254b55765479e9b8766?rp=1&ru=/activity/oj&qru=/ta/cracking-the-coding-interview/question-ranking
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: