求一个数组里的数的所有组合和全排列(Java)

题目:

把一个数组里的数的组合全部列出,比如1和2列来为1,2,12,21.


分析:

这道题有多种扩展

1,没有重复元素的数的组合

2,有重复元素的数的组合

3,没有重复元素的数的全排列

4,有重复元素的数的全排列


1,没有重复元素的数的组合

第一种情况下,没有重复元素的数的组合,利用DFS直接求,因为没有重复元素,所以不会出现一样的,将数组元素存在LinkedList里(方便删除),遍历List,删除当前元素并把此元素加入结果,如果结果长度不为0,则输出,以此递归。

	public static void DFS(List<Integer> candidate, String prefix){
		if(prefix.length()!=0){
			System.out.println(prefix);
		}
		
		
		for(int i=0; i<candidate.size(); i++){
			
			List<Integer> temp = new LinkedList<Integer>(candidate);
			int item = (int)temp.remove(i);  // 取出被删除的元素,这个元素当作一个组合用掉了
			DFS(temp, prefix+item);
		}
	}
	public static void main(String[] args) {
		
		Integer[] array = {1,2};
		List<Integer> list = Arrays.asList(array);
		DFS(list, "");
	}

2,有重复元素的数的组合

第二种情况,存在重复元素,如果直接用第一种情况的代码直接使用,可能会存在重复的,这里的处理方法是把结果保存在一个HashSet里,每得到一个结果,检查HashSet里是否已经存在,不存在才输出。

    public static void DFS(List<Integer> candidate, String prefix, HashSet<String> hs){
		if(prefix.length()!=0 && !hs.contains(prefix)){
			System.out.println(prefix);
			hs.add(prefix);
		}
		
		
		for(int i=0; i<candidate.size(); i++){
			
			List<Integer> temp = new LinkedList<Integer>(candidate);
			int item = (int)temp.remove(i);
			DFS(temp, prefix+item, hs);
		}
	}
	public static void main(String[] args) {
		
		Integer[] array = {1,1,2};
		List<Integer> list = Arrays.asList(array);
		HashSet<String> hs = new HashSet<String>();
		DFS(list, "", hs);
	}

3,没有重复元素的数的全排列

这种情况是全排列,所以只需要在第一种情况的输出时,多加一个判断条件,此时的输入List 中无数据(说明已经全部使用来排列了)。

    public static void DFS(List<Integer> candidate, String prefix){
		if(prefix.length()!=0 && candidate.size()==0){
			System.out.println(prefix);
		}
		
		
		for(int i=0; i<candidate.size(); i++){
			
			List<Integer> temp = new LinkedList<Integer>(candidate);
			int item = (int)temp.remove(i);  // 取出被删除的元素,这个元素当作一个组合用掉了
			DFS(temp, prefix+item);
		}
	}
	public static void main(String[] args) {
		
		Integer[] array = {1,2};
		List<Integer> list = Arrays.asList(array);
		DFS(list, "");
	}

4,有重复元素的数的全排列

这种情况是全排列,有重复元素,是第二种情况的扩展,所以只需要在第二种情况的输出时,多加一个判断条件,此时的输入List 中无数据(说明已经全部使用来排列了)。

    public static void DFS(List<Integer> candidate, String prefix, HashSet<String> hs){
		if(prefix.length()!=0 && !hs.contains(prefix) && candidate.size()==0){
			System.out.println(prefix);
			hs.add(prefix);
		}
		
		
		for(int i=0; i<candidate.size(); i++){
			
			List<Integer> temp = new LinkedList<Integer>(candidate);
			int item = (int)temp.remove(i);
			DFS(temp, prefix+item, hs);
		}
	}
	public static void main(String[] args) {
		
		Integer[] array = {1,1,2};
		List<Integer> list = Arrays.asList(array);
		HashSet<String> hs = new HashSet<String>();
		DFS(list, "", hs);
	}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值