您的位置:首页 > 其它

集合的子集

2016-10-10 08:46 197 查看
题目描述

请编写一个方法,返回某集合的所有非空子集。

给定一个int数组A和数组的大小int n,请返回A的所有非空子集。保证A的元素个数小于等于20,且元素互异。各子集内部从大到小排序,子集之间字典逆序排序,见样例。

测试样例:

[123,456,789]

返回:{[789,456,123],[789,456],[789,123],[789],[456 123],[456],[123]}

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Scanner;

public class Subset {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner = new Scanner(System.in);
while(scanner.hasNext()){
int n = scanner.nextInt();
int[] A = new int
;
for (int i = 0; i < n; i++) {
A[i] = scanner.nextInt();
}
ArrayList<ArrayList<Integer>> subsets = getSubsets1(A, n);
for(int i=0;i<subsets.size();i++){
for(int j=0;j<subsets.get(i).size();j++){
System.out.print(subsets.get(i).get(j) + " ");
}
System.out.println();
}
}
}

// 方法1 占位法
public static ArrayList<ArrayList<Integer>> getSubsets(int[] A, int n) {
ArrayList<ArrayList<Integer>> subsets = new ArrayList<ArrayList<Integer>>();
int size = 1 << n;// 子集的大小(算上了空集)
for (int i = 0; i < size; i++) {
ArrayList<Integer> subList = new ArrayList<Integer>();
int k = i;
int index = 0;
while (k > 0) {
if ((k & 1) == 1) {
subList.add(A[index]);
}
k >>= 1;
index++;
}
Collections.reverse(subList);
if (subList.size() > 0) {// 除去空集
subsets.add(subList);
}
}
Collections.reverse(subsets);
return subsets;
}

// 方法2 举个例子一目了然
// 比如 A={1,2,3};
/*
* 1.首先生成一个元素的子集sets(1)={{1}}。
* 2.加入元素2,则sets(2)由三部分组成:
* (1)在sets(1)的所有子集前边插入当前元素A[1]=2,得{{2,1}};
* (2)A[1]单独作为一个子集{2};
* (3)sets(1)同时也应包含到sets(2)中,sets(2) = {{2,1},{2},{1}}。
* 3.加入元素3,则sets(3)由三部分组成:
* (1)在sets(2)的所有子集前边插入当前元素A[2]=3,得{{3,2,1},{3,2},{3,1}};
* (2)A[2]单独作为一个子集{3};
* (3)sets(2)同时也应包含到sets(3)中,sets(3) = {{3,2,1},{3,2},{3,1},{3},{2,1},{2},{1}}。
*/
public static ArrayList<ArrayList<Integer>> getSubsets1(int[] A, int n) {
Arrays.sort(A);// 先从小到大排序
ArrayList<ArrayList<Integer>> outSet = new ArrayList<ArrayList<Integer>>(); // 表示整体的大集合
ArrayList<Integer> inSet; // 集合元素
if (n == 1) { //递归终止条件
inSet = new ArrayList<Integer>();
inSet.add(A[0]);
outSet.add(inSet);
return outSet;
}
ArrayList<ArrayList<Integer>> temp = getSubsets1(A, n - 1); // 取得sets(n-1)集合
for (int i = 0; i < temp.size(); i++) { // 在sets(n-1)的所有子集前边插入当前元素A[n-1]
inSet = new ArrayList<Integer>();
inSet.add(A[n - 1]);
for (int j = 0; j < temp.get(i).size(); j++) {
inSet.add(temp.get(i).get(j));
}
outSet.add(inSet);
}
inSet = new ArrayList<Integer>();
inSet.add(A[n - 1]); // A[n-1]单独作为一个子集
outSet.add(inSet);
outSet.addAll(temp);// sets(n-1)同时也应包含到sets(n)中
return outSet;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  子集