子集算法

子集数量=2 ^ n = 1 (空集) + (2^n-1) (非空子集)
算法原理:每个元素有两种处理方式,取或不取,共2 ^ n 种组合

递归算法

boolean[] done 为标志数组,表明对应位置元素取或不取

public static void recursion(int[] root) {
		Objects.requireNonNull(root);
		boolean[] done=new boolean[root.length];
		recursion(root,0,done);
	}
	public static void recursion(int[] root,int index,boolean[] done) {
		if(root.length>index) {
			//保留root[index]
			done[index]=true;
			recursion(root,index+1,done);
			//复原标志数组
			done[index]=false;
			//不保留root[index]
			recursion(root,index+1,done);	
		}else {
			//打印
			StringBuffer buffer=new StringBuffer();
			buffer.append("[");
			for(int i=0;i<done.length;i++) {
				if(done[i]) {
					buffer.append(root[i]+",");
				}
			}
			if(buffer.length()>1) {
				buffer.deleteCharAt(buffer.length()-1);
			}
			buffer.append("]");
			System.out.println(buffer);
		}
	}

测试

	int [] a=new int[] {1,2,3,4};
	recursion(a);

输出:
[1,2,3,4]
[1,2,3]
[1,2,4]
[1,2]
[1,3,4]
[1,3]
[1,4]
[1]
[2,3,4]
[2,3]
[2,4]
[2]
[3,4]
[3]
[4]
[]

迭代法

共2 ^ n 种组合,对第k个组合,将k看作二进制数,那么它的对应位0,1就表明对应元素取或不取

class ComItr implements Iterator<List<Integer>>{
	private long title;
	private long count=0;
	public int[]root;

	public ComItr(int[] root) {
		this.root=root;
		title=1<<root.length;
	}
	public boolean hasNext() {
		return title>count;
	}
	public List<Integer> next() {
		ArrayList<Integer> list=new ArrayList<Integer>() ;
		for(int i=0;i<root.length;i++) {
			if(((1<<i)&count)!=0) {
				list.add(root[i]);
			}
		}
		count++;
		return list;
	}
}

测试

	int [] a=new int[] {1,2,3,4};
	ComItr itr=new ComItr(a);
	while(itr.hasNext()) {
		System.out.println(itr.next());
	}

[]
[1]
[2]
[1, 2]
[3]
[1, 3]
[2, 3]
[1, 2, 3]
[4]
[1, 4]
[2, 4]
[1, 2, 4]
[3, 4]
[1, 3, 4]
[2, 3, 4]
[1, 2, 3, 4]

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值