java实现全排列输出

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

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

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

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

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

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

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

 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 }

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

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

 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都在一个项目下:

希望能对大家有所帮助!

java实现全排列输出的更多相关文章

  1. n全排列输出和 n个数的组合(数字范围a~b)

    n全排列输出: int WPermutation(int num, bool bRepeat) num表示num全排列 bRepeat标志是否产生重复元素的序列. int Permutation(in ...

  2. JAVA中集合输出的四种方式

    在JAVA中Collection输出有四种方式,分别如下: 一) Iterator输出. 该方式适用于Collection的所有子类. public class Hello { public stat ...

  3. Java数字格式化输出时前面补0

    Java数字格式化输出时前面补0 星期日 2014年11月30日|  分类: Java     /** * 里数字转字符串前面自动补0的实现. * */ public class TestString ...

  4. Java自定义日志输出文件

    Java自定义日志输出文件 日志的打印,在程序中是必不可少的,如果需要将不同的日志打印到不同的地方,则需要定义不同的Appender,然后定义每一个Appender的日志级别.打印形式和日志的输出路径 ...

  5. Java中直接输出一个类的对象

    例如 package com.atguigu.java.fanshe; public class Person { String name; private int age; public Strin ...

  6. 【JAVA零基础入门系列】Day7 Java输入与输出

    [JAVA零基础入门系列](已完结)导航目录 Day1 开发环境搭建 Day2 Java集成开发环境IDEA Day3 Java基本数据类型 Day4 变量与常量 Day5 Java中的运算符 Day ...

  7. Java中如何输出对勾,ASCII编码与字符串相互转换

    Java中如何输出对勾? 最简单的方法是,从那个地方拷贝一个对勾的字符,然后System.out.println("√"); 但是心里总会担心,万一机器不认这个字符该怎么办?(可能 ...

  8. Java-Runoob-高级教程-实例-数组:05. Java 实例 – 数组输出

    ylbtech-Java-Runoob-高级教程-实例-数组:05. Java 实例 – 数组输出 1.返回顶部 1. Java 实例 - 数组输出  Java 实例 以下实例演示了如何通过循环输出数 ...

  9. JS实现的数组全排列输出算法

    本文实例讲述了JS实现的数组全排列输出算法.分享给大家供大家参考.具体分析如下: 这段js代码对数组进行全排列输出,改进了一些老的代码 从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来, ...

随机推荐

  1. springboot-3-web开发

    一.视图层技术thymeleaf 我们一般都是基于3.x版本 1.流程: 导入依赖 <!--整合thymeleaf技术--> <dependency> <groupId& ...

  2. 10、Java——内部类

    ​  1.类中定义类 (1)当一类中的成员,作为另外一种事物的时候,这个成员就可以定义为内部类. (2)分类:①成员内部类 ②静态内部类 ③私有内部类 ④局部内部类 ⑤匿名内部类 ⑥Lambda表达式 ...

  3. P7324 [WC2021] 表达式求值

    P7324 [WC2021] 表达式求值 闲话 WC2021 我只得了 20 分,三道题总共 20 分.我是下场了突然后知后觉这件事的,主要原因是我开了 C++11,然后 T1 T2 都没分了.在洛谷 ...

  4. Angular封装WangEditor富文本组件

    富文本组件是web程序中很常用的一个组件,特别是要开发一个博客,论坛这类的网站后台. 得益于Angular的强大,封装WangEditor组件非常简单 1.使用yarn或者npm安装wangedito ...

  5. 1.1 MATLAB系统环境

    专题一 MATLAB基础知识 1.1 MATLAB系统环境 1. 续行符(三个点) 2. 当前文件夹 先建立当前文件夹,再cd 3.工作区窗口 4.搜索路径       01当前文件夹下的程序文件 变 ...

  6. springboot整合mybatis源码分析

    springboot整合mybatis源码分析 本文主要讲述mybatis在springboot中是如何被加载执行的,由于涉及的内容会比较多,所以这次只会对调用关系及关键代码点进行讲解,为了避免文章太 ...

  7. 10分钟物联网设备接入阿里云IoT平台

    前言最近尝试了一下阿里云IoT物联网平台,还是蛮强大的.在此记录一下学习过程.本教程不需要任何外围硬件,一台电脑和一根能上网的网线即可.算是一篇Hello World了.先上效果图 第一章 准备工作1 ...

  8. 微信小程序对接显示阿里云数据库数据

    现实需求 在项目中需求,有时候现场设备发生故障,需要远程的人员知道.除了邮件方式,以微信小程序的方式也很好.今天进行尝试,并制作了一个demo版本. 1.微信小程序申请制作前端 1.1lists文件( ...

  9. OpenFaaS实战之五:大话watchdog

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  10. .NET 6 预览版 7 发布——最后一个预览版

    原文:bit.ly/2VJxjxQ 作者:Richard 翻译:精致码农-王亮 说明:文中有大量的超链接,这些链接在公众号文章中被自动剔除,一部分包含超链接列表的小段落被我删减了,如果你对此感兴趣,请 ...