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

来源:互联网 发布:网络管理规章制度 编辑:程序博客网 时间:2024/05/24 20:07

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

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中排列组合的一些理解,也许有更好的算法,也请大神指教。

原创粉丝点击