java递归算法中的排列组合问题及排列组合去重

之前学习递归算法的时候一直来不及总结一下,也花了一些时间去理解排列组合中的实现问题,现在总结一下,希望对大家能有帮助

1. 排列问题

问题:由a、b、c三个字母随机组成的所有排列情况

思路:首先 先确定第一位字母,例如确定了a,则情况就变成了a与剩下两位字母的随机组合,这里就是递归实现,自身实现自身方法。当列出了所以以a为启示的情况后,a与b交换 ,交换后仍然是递归方法。之后a与c进行交换。注意a和b递归完,恢复原来的位置,然后再让 a与c换位子,不然换的则是b与c。

下面是代码

package test;

public class pailie {
	public static void p(char[] array, int index){
		char temp;
		if(index==array.length){
			System.out.println(array);
			return;
		}
		if(array.length==0||index<0||index>array.length){
			return;
		}
		for(int j=index;j<array.length;j++){
			temp=array[j];
			array[j]=array[index];
			array[index]=temp;
			p(array, index+1);
			temp=array[j];
			array[j]=array[index];
			array[index]=temp;
		}
		
	}
	public static void main(String[] args) {
		char[] chars={'a','b','c'};

		      p(chars,0);

	}
}

2. 组合问题

问题:有a,b,c三个字母,让它们随机组合,可以有[a],[a,b],[a,c]等许多组合结果

思路:用一个arraylist储存数组结果,每次取多少个字母设置为number参数进行循环,number可以为1,2,3。即随机从组合里抽1个字母/2个字母/3个字母。第三个参数是从第几个字母开始取number个字母,如果从a开始取字母,则组合情况包含两种。一种就是包含a参数的,剩下的number-1随机组合(递归思想)。另一种就是不包含参数a的,剩下的number字母随机组合(递归思想)。因此实现起来的代码如下

package test;

import java.util.ArrayList;
import java.util.List;

public class zuhe {
    public void p(char[] arrays, int begin, int number, List<Character> list){
    	
    	if(number==0){
    		System.out.println(list.toString());
    		return;
    	}
    	if(begin==arrays.length){
    		return;
    	}
    	list.add(arrays[begin]);
    	p(arrays, begin+1, number-1,list);
    	list.remove((Character)arrays[begin]);
    	p(arrays, begin+1, number,list);
    }
	public static void main(String[] args) {
		char[] arrays={'a','b','c'};
		zuhe zuhe=new zuhe();
		List<Character> list= new ArrayList();
		for(int number=1;number<=arrays.length;number++){
		zuhe.p(arrays,0,number,list);
		}
	}

}

3. 排列去重问题

问题:有数字12234,对它们随机进行排列,不允许有重复

思路:采用排列的递归思想,在这基础之上,对交换数字时进行判断,如果要交换的数字在之前已存在,则不交换,返回false;如果要交换的数字不存在,则交换,继续递归。改进后的代码如下

package test;

import java.util.ArrayList;

import java.util.HashSet;
import java.util.Iterator;

public class pailie1 {
	static int k=0;
	static HashSet<char[]> set=new HashSet<char[]>();
	static ArrayList<Character> list=new ArrayList<Character>();
    public boolean isSwap(char[] num , int i ,int j)  
    {  
        for(int index = i;index<j;index++)  
        {  
            if(num[index]==num[j])  
                return false;  
        }  
        return true;  
    }  
	public void p(char[] array,int index){
		char temp;
		
		if(index<0||index>array.length){
			return;
		}
		if(index==array.length){
			System.out.println(array);
//			set.add(array);
			k++;
		}
		for(int j=index;j<array.length;j++){
			if(isSwap(array, index, j)){
			temp=array[j];
			array[j]=array[index];
			array[index]=temp;
			p(array, index+1);
			temp=array[j];
			array[j]=array[index];
			array[index]=temp;

			}else{
				continue;
			}
			
			}
			
		
	}
	public static void main(String[] args) {
		String s="12234";
		char[] c=s.toCharArray();
		pailie1 pailie=new pailie1();
		pailie.p(c,0);
		System.out.println(k);


	}

}

最后一行输出了总数,运用数学计算排列问题总共有60中,总数验证正确性,也为60。


4. 组合中的去重问题

问题:有数字1223,让它们两两组合,不能有重复。

思路:采用hashset加入到组合算法中,代码如下

package test;

import java.util.ArrayList;

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

public class zuhe1 {
	static int k=0;
	static HashSet<String> set;

    public void p(char[] arrays,int begin, int number, ArrayList<Character> list){
    	if(number==0){
//    		System.out.println(list.toString());
    		k++;
    		set.add(list.toString());
    		return;
    	}
    	if(begin==arrays.length){
    		return;
    	}

    	list.add(arrays[begin]);
    	p(arrays, begin+1, number-1, list);
    	list.remove((Character)arrays[begin]);
    	p(arrays, begin+1, number, list);
    }
	public static void main(String[] args) {
		String s="1223";
		char[] arrays=s.toCharArray();
		zuhe1 zuhe1=new zuhe1();
		ArrayList<Character> list=new ArrayList<Character>();
		for(int number=1;number<arrays.length+1;number++){
		set=new HashSet<String>();
		zuhe1.p(arrays,0,number,list);
		Iterator<String> it=set.iterator();
		while(it.hasNext()){
			String a=it.next();
			System.out.println(a);
		}
		}
	}

}

以上是我对java中排列组合的一些理解,也许有更好的算法,也请大神指教。

    原文作者:递归算法
    原文地址: https://blog.csdn.net/qq_19301269/article/details/78560019
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞