java 全排列 输出_java实现全排列输出

java实现全排列输出

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

最近在找工作,面试java程序员或者软件工程师,在笔试的时候常常见到这么一道题:全排列

的输出数组(常常要求是整数),其实这道题不难,主要是递归调用,在baidu或者google上已经有很多人提出了解法,但是大部分可读性很差,让我们

莘莘学子根本就记不住。我来简单的说一下:

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

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

69c5a8ac3fa60e0848d784a6dd461da6.png1 public递归方法(参数列表){2 if(列表的元素只有两个){3 输出:“元素一元素二”4 输出:“元素二元素一”5 }else{6 //此时元素有两个以上,这时候要使用递归

7 递归方法(参数列表)//使用递归方法将元素细分

8 }9 }

69c5a8ac3fa60e0848d784a6dd461da6.png

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

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

69c5a8ac3fa60e0848d784a6dd461da6.png1 importjava.util.LinkedList;2 importjava.util.List;3

4

5 public classListAllPrint {6 /**

7 * 使用createList方法,填充参数列表传递过来的List,默认是Integer,一般是这个类型,你可以修改别的类型8 */

9 public void createList(intn,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 voidprintAll(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 = newLinkedList(candidate);32 printAll(temp, prefix + temp.remove(i));//递归调用

33 }34 }35 }36

37 /**

38 * 测试代码39 */

40 public static voidmain(String[] args) {41 //TODO Auto-generated method stub

42 LinkedList list=new LinkedList();43 ListAllPrint lap=newListAllPrint();44 lap.createList(3, list);45 lap.printAll(list,"");46 }47 }

69c5a8ac3fa60e0848d784a6dd461da6.png

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

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,从而结束输出,从而使代码显得漂亮多了。修改如下:

69c5a8ac3fa60e0848d784a6dd461da6.png1 importjava.util.ArrayList;2 importjava.util.LinkedList;3 importjava.util.List;4

5

6 public classListAllPrint2 {7 /**

8 * 使用createList方法,填充参数列表传递过来的List,默认是Integer,一般是这个类型,你可以修改别的类型9 */

10 public void createList(intn,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,intlength){24 if(prefix.length()==length)25 System.out.println(prefix);26 for (int i = 0; i < candidate.size(); i++) {27 List temp = newLinkedList(candidate);28 printAll(temp, prefix +temp.remove(i),length);29 }30 }31

32 /**

33 * 测试代码34 */

35 public static voidmain(String[] args) {36 //TODO Auto-generated method stub

37 ArrayList list=new ArrayList();38 ListAllPrint2 lap=newListAllPrint2();39 lap.createList(3, list);40 lap.printAll(list,"",list.size());41 }42 }

69c5a8ac3fa60e0848d784a6dd461da6.png

这样子看上去漂亮多了!

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

希望能对大家有所帮助!

原文:http://www.cnblogs.com/wanghui390/p/3632519.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值