java实现全排列输出

来源:互联网 发布:js向div中添加图片 编辑:程序博客网 时间:2024/06/05 15:03

Java 全排列输出


java实现全排列输出

最近在找工作,面试java程序员或者软件工程师,在笔试的时候常常见到这么一道题:全排列的输出数组(常常要求是整数),其实这道题不难,主要是递归调用,在baidu或者google上已经有很多人提出了解法,但是大部分可读性很差,让我们莘莘学子根本就记不住。我来简单的说一下:

其实这个问题的解法基本思路是这样的:递归

但是我们在使用递归的时候要注意结束条件,也就是递归到最后,要推出递归方法,目前网上的主要思路如下:

 

Java代码  收藏代码
  1. public 递归方法(参数列表){  
  2.       if(列表的元素只有两个){  
  3.            输出:“元素一元素二”  
  4.        输出:“元素二元素一”  
  5.     }else{  
  6.        //此时元素有两个以上,这时候要使用递归  
  7.         递归方法(参数列表)//使用递归方法将元素细分  
  8.     }  
  9. }  

 

我这个思路是在百度上看到的,但是具体链接和源代码我再没找到,因为那个代码很乱……Sorry!

我在Eclipse实现了这个思路,代码如下:

Java代码  收藏代码
  1. import java.util.LinkedList;  
  2. import java.util.List;  
  3.   
  4.   
  5. public class ListAllPrint {  
  6.     /** 
  7.      * 使用createList方法,填充参数列表传递过来的List,默认是Integer,一般是这个类型,你可以修改别的类型 
  8.      */  
  9.     public void createList(int n,List list){  
  10.         if(n==0){//当是n=0是,默认就是3了  
  11.             n=3;  
  12.         }  
  13.         for(int i=1;i<=n;i++){//for循环填充list  
  14.             list.add(i);  
  15.         }  
  16.     }  
  17.     /** 
  18.      * printAll是输出全排列的递归调用方法,list是传入的list,用LinkedList实现,而prefix用于转载以及输出的数据 
  19.      */  
  20.     public void printAll(List candidate, String prefix){  
  21.         if(candidate.size()==1){  
  22.             //一个元素时候,输出……;不过这个实现,这个if传递不到递归中,仅仅是测试代码中list的size为1时调用一次  
  23.              System.out.println(candidate.get(0));  
  24.         }  
  25.         if(candidate.size()==2){  
  26.             //输出两个元素时候,颠倒顺序  
  27.              System.out.println(prefix+candidate.get(0)+candidate.get(1));  
  28.              System.out.println(prefix+candidate.get(1)+candidate.get(0));  
  29.         }else{  
  30.             for (int i = 0; i < candidate.size(); i++) {  
  31.                  List temp = new LinkedList(candidate);  
  32.                  printAll(temp, prefix + temp.remove(i));//递归调用  
  33.             }  
  34.         }  
  35.     }  
  36.   
  37.     /** 
  38.      * 测试代码 
  39.      */  
  40.     public static void main(String[] args) {  
  41.         // TODO Auto-generated method stub  
  42.         LinkedList<Integer> list=new LinkedList<Integer>();  
  43.         ListAllPrint lap=new ListAllPrint();  
  44.         lap.createList(3, list);  
  45.         lap.printAll(list,"");  
  46.     }  
  47. }  

 

我在编写这个程序的时候,发现自己要写一个

 

Java代码  收藏代码
  1. if(candidate.size()==1){  
  2.             //一个元素时候,输出……;不过这个实现,这个if传递不到递归中,仅仅是测试代码中list的size为1时调用一次  
  3.              System.out.println(candidate.get(0));  
  4.         }  

 语句,用来当list初始就为size就为1时使用。我觉得这个效率很差,不仅每次递归也判断,而且不符合递归的思想:递归到最后应该是一个元素(查找算法递归实现最后是一个元素的判断)

所以,我又添加了一个参数在递归的方法中,用来记录原list的长度,使得每次的排列字符串输出可以完全记载到第二个参数prefix,不使用2,而是使用length来判断是否加最后一个元素入prefix,从而结束输出,从而使代码显得漂亮多了。修改如下:

Java代码  收藏代码
  1. import java.util.ArrayList;  
  2. import java.util.LinkedList;  
  3. import java.util.List;  
  4.   
  5.   
  6. public class ListAllPrint2 {  
  7.     /** 
  8.      * 使用createList方法,填充参数列表传递过来的List,默认是Integer,一般是这个类型,你可以修改别的类型 
  9.      */  
  10.     public void createList(int n,List list){  
  11.         if(n==0){  
  12.             n=3;  
  13.         }  
  14.         for(int i=1;i<=n;i++){  
  15.             list.add(i);  
  16.         }  
  17.     }  
  18.     /** 
  19.      * printAll是输出全排列的递归调用方法,list是传入的list,用LinkedList实现, 
  20.      * 而prefix用于转载以及输出的数据 
  21.      * length用于记载初始list的长度,用于判断程序结束。 
  22.      */  
  23.     public void printAll(List candidate, String prefix,int length){  
  24.         if(prefix.length()==length)  
  25.              System.out.println(prefix);  
  26.         for (int i = 0; i < candidate.size(); i++) {  
  27.              List temp = new LinkedList(candidate);  
  28.              printAll(temp, prefix + temp.remove(i),length);  
  29.         }  
  30.     }  
  31.   
  32.     /** 
  33.      * 测试代码 
  34.      */  
  35.     public static void main(String[] args) {  
  36.         // TODO Auto-generated method stub  
  37.         ArrayList<Integer> list=new ArrayList<Integer>();  
  38.         ListAllPrint2 lap=new ListAllPrint2();  
  39.         lap.createList(3, list);  
  40.         lap.printAll(list,"",list.size());  
  41.     }  
  42. }  

 

这样子看上去漂亮多了!

呵呵,相关的project文件如下,这两个class都在一个项目下:

希望能对大家有所帮助!

转载自:http://easonfans.iteye.com/blog/517286

0 0