Leetcode031--集合的所有子集

一、原题



Given a set of distinct integers, nums, return all possible subsets. 
Note: 
Elements in a subset must be in non-descending order. 
The solution set must not contain duplicate subsets. 
For example, 
If nums = [1,2,3], a solution is:

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


一、中文


给定一个不同数字的数组,返回它的所有子集。 



三、举例



给定一个不同数字的数组,返回它的所有子集。


四、思路



先对数组中的元素进行排序,然后再用递归分治法进行求解。 


五、程序


先对数组中的元素进行排序,然后再用递归分治法进行求解。 
package code;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class LeetCode44{
	
    private static ArrayList<ArrayList<Integer>> result;
    private static ArrayList<Integer> l;
    private static int[] tmpset;
    private static int numer; // 在set中还需要的选择的元素个数
	
	public static void main(String args[]){
		int num[] = new int[]{1, 3, 2, 4};
		
//		ArrayList<ArrayList<Integer>> allSubset = findAllSubset(num);
//		Iterator<ArrayList<Integer>> it1 = allSubset.iterator();
		
//		while(it1.hasNext()){
//			Iterator<Integer> it2 = it1.next().iterator();
//			while(it2.hasNext()){
//				System.out.print(it2.next()+" ");
//			}
//			System.out.println();
//		}
		
		
		Set<Set<Integer>> result = getSubSet(num);	//调用方法
		//输出结果
		for(Set<Integer> subSet: result){
			for(Integer i: subSet)
				System.out.print(i+" ");
			
			System.out.println("");
		}

	}


	//数组表示的数字进行加一操作,数组的最高位表示的是数字的最低位
	public static ArrayList<ArrayList<Integer>> findAllSubset(int set[]) {
		result = new ArrayList<ArrayList<Integer>>();
		
		if(set != null){
			l = new ArrayList<>();
			
            // 对S进行排序处理
            quickSort(set, 0, set.length - 1);
            
            tmpset = set;
            for (int i = 0; i <= set.length; i++) {
                numer = i;
                subset(0);
            }
		}
		
		return result;
    }


	public static Set<Set<Integer>> getSubSet(int[] set){
		Set<Set<Integer>> result = new HashSet<Set<Integer>>();	//用来存放子集的集合,如{{},{1},{2},{1,2}}
		int length = set.length;
		int num = length==0 ? 0 : 1<<(length);	//2的n次方,若集合set为空,num为0;若集合set有4个元素,那么num为16.
		
		//从0到2^n-1([00...00]到[11...11])
		for(int i = 0; i < num; i++){		
			Set<Integer> subSet = new HashSet<Integer>();
			
			int index = i;
			for(int j = 0; j < length; j++){
				if((index & 1) == 1){		//每次判断index最低位是否为1,为1则把集合set的第j个元素放到子集中
					subSet.add(set[j]);
				}
				index >>= 1;		//右移一位
			}
			
			result.add(subSet);		//把子集存储起来
		}
		return result;
	}
	
	
	//通过递归的方式来进行
	public static void subset(int start) {
		
        if (numer == 0) {
            ArrayList<Integer> tmp = new ArrayList<>();
            for (Integer i : l) {
                tmp.add(i);
            }

            result.add(tmp);
            return;
        }
		
		int endFirst = tmpset.length - numer; // 剩余的要挑选的num个元素中,第一个的最大下标
        for (int i = start; i <= endFirst; i++) {
            l.add(tmpset[i]);
            numer--;
            subset(i + 1);
            numer++;
            l.remove(new Integer(tmpset[i]));
        }
	}


	//快速排序
	public static void quickSort(int num[], int left, int right){
		if(left < right){
			int mid = getMid(num, left, right);
			quickSort(num, left, mid-1);
			quickSort(num, left+1, right);
		}
	}
	
	//通过交换的方式将两边进行排序,并返回中间的位置
	public static int getMid(int num[], int left, int right){
		int tmp = num[left];
		while(left < right){
			while(left < right && num[right] > tmp){
				right--;
			}
			num[left] = num[right];
			
			while(left < right && num[left] < tmp){
				left++;
			}
			num[right] = num[left];
		}
		
		num[left] = tmp;
		
		return left;
	}

}
	

------------------------------------------output----------------------------------------

1 
2 
3 
1 2 
1 3 
4 
2 3 
1 4 
1 2 3 
2 4 
3 4 
1 2 4 
1 3 4 
2 3 4 
1 2 3 4 



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值