生成非空集合(逐步生成结果-二进制解法)

1. 问题描述:

 请编写一个方法,返回某集合的所有非空子集。
 给定一个int数组A和数组的大小int n,请返回A的所有非空子集。
 保证A的元素个数小于等于20,且元素互异

2. 我们除了可以使用递归和递推的方法,此外我们还有一种更有技巧性的方法,那就是二进制的解法

假如数组的长度为3,那么它的非空集合的个数就为0 ~ 2 ^ n  - 1, 而在这个区间的这些数字的二进制位上的数字我们可以技巧性的使用,那就是该位上为1,就选择某位上对应的数字

下面以{1, 2 ,3}为例:

1 1 1      3 2 1

1 1 0      3 2

1 0 1      3 1

1 0 0      3

0 1 1      2 1

0 1 0      2 

0 0 1      1 

上面是用到的是字典序逆序排列之后得到的非空集合(需要从高位进行处理)

3. 具体的代码如下:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
public class Main {
	//二进制上的数字代表该为是选择还是不选
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int A[] = new int[n];
		for(int i = 0; i < n; i++){
			A[i] = sc.nextInt();
		}
		List<List<Integer>> list = solve(A, n);
		for(List<Integer> listOut : list){
			if(listOut.size() == 0){
				list.remove(listOut);
				break;
			}
		}
		System.out.println(list);
		sc.close();
	}

	private static List<List<Integer>> solve(int[] A, int n){
		Arrays.sort(A);
		List<List<Integer>> list = new ArrayList<>();
		int nExp = (int) Math.pow(2, n);
		for(int i = nExp; i > 0; i--){
			List<Integer> listNew = new ArrayList<>();
			for(int j = n - 1; j >= 0; j--){
				//检查哪一位上的数字为1
				if(((i >> j) & 1) == 1){
					listNew.add(A[j]);
				}
			}	
			list.add(listNew);
		}
		return list;
	}
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值