集合的子集
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
给定一个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
相关文章推荐
- 多线程概述
- LEETCODE 206
- Spring3.1新属性管理API:PropertySource、Environment、Profile
- Quartz源码分析之HelloWorld示例
- 小学生算术能力测试系统
- 类和对象&重载
- MVC框架简谈与在Android中的应用
- codevs 1349 板猪的火车票
- 更新安装xcode7插件
- objective-C学习笔记(五)函数成员:初始化器和析构器
- android 之 启动画面的两种方法
- CentOS 下安装apt-get
- 软件项目管理第三周作业
- php 封装Memcache 队列缓存类
- MyBatis Mapper接口实现原理
- linux c++线程池开发demo
- POJ Mayor's posters (线段树成段更新 离散化666)
- Django--models一对多实例
- RunLoop基础
- Problem A: 删除区间内的元素(线性表)