java实现全排列输出
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实现全排列输出的更多相关文章
- n全排列输出和 n个数的组合(数字范围a~b)
n全排列输出: int WPermutation(int num, bool bRepeat) num表示num全排列 bRepeat标志是否产生重复元素的序列. int Permutation(in ...
- JAVA中集合输出的四种方式
在JAVA中Collection输出有四种方式,分别如下: 一) Iterator输出. 该方式适用于Collection的所有子类. public class Hello { public stat ...
- Java数字格式化输出时前面补0
Java数字格式化输出时前面补0 星期日 2014年11月30日| 分类: Java /** * 里数字转字符串前面自动补0的实现. * */ public class TestString ...
- Java自定义日志输出文件
Java自定义日志输出文件 日志的打印,在程序中是必不可少的,如果需要将不同的日志打印到不同的地方,则需要定义不同的Appender,然后定义每一个Appender的日志级别.打印形式和日志的输出路径 ...
- Java中直接输出一个类的对象
例如 package com.atguigu.java.fanshe; public class Person { String name; private int age; public Strin ...
- 【JAVA零基础入门系列】Day7 Java输入与输出
[JAVA零基础入门系列](已完结)导航目录 Day1 开发环境搭建 Day2 Java集成开发环境IDEA Day3 Java基本数据类型 Day4 变量与常量 Day5 Java中的运算符 Day ...
- Java中如何输出对勾,ASCII编码与字符串相互转换
Java中如何输出对勾? 最简单的方法是,从那个地方拷贝一个对勾的字符,然后System.out.println("√"); 但是心里总会担心,万一机器不认这个字符该怎么办?(可能 ...
- Java-Runoob-高级教程-实例-数组:05. Java 实例 – 数组输出
ylbtech-Java-Runoob-高级教程-实例-数组:05. Java 实例 – 数组输出 1.返回顶部 1. Java 实例 - 数组输出 Java 实例 以下实例演示了如何通过循环输出数 ...
- JS实现的数组全排列输出算法
本文实例讲述了JS实现的数组全排列输出算法.分享给大家供大家参考.具体分析如下: 这段js代码对数组进行全排列输出,改进了一些老的代码 从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来, ...
随机推荐
- 大疆M3508、M2006必备CAN总线知识与配置方法
使用大疆M3508.M2006的CAN总线知识与配置方法 目录 使用大疆M3508.M2006的CAN总线知识与配置方法 前言: 0x00 需要额外的CAN收发器!!! 0x01 硬件层面分析 为什么 ...
- 【LeetCode】151. 翻转字符串里的单词(剑指offer 58-I)
151. 翻转字符串里的单词 知识点:字符串:双指针 题目描述 给你一个字符串 s ,逐个翻转字符串中的所有 单词 . 单词 是由非空格字符组成的字符串.s 中使用至少一个空格将字符串中的 单词 分隔 ...
- 基于 apache-arrow 的 duckdb rust 客户端
背景 duckdb 是一个 C++ 编写的单机版嵌入式分析型数据库.它刚开源的时候是对标 SQLite 的列存数据库,并提供与 SQLite 一样的易用性,编译成一个头文件和一个 cpp 文件就可以在 ...
- 【洛谷P1816 忠诚】线段树
题目描述 老管家是一个聪明能干的人.他为财主工作了整整10年,财主为了让自已账目更加清楚.要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意.但是由于一些人的挑拨,财主还是对管家产生了 ...
- GeoServer Rest服务启动匿名认证的配置方法
GeoServer Rest服务数据默认需要进行用户名.密码的认证,如不需进行该认证,则启动匿名认证即可,配置方式如下(针对war包发布的GeoServer应用): 在GeoServer war包的解 ...
- Mysql分区表使用
一.什么是分区表 分区表就是按一定规则将一张表分割成多个部分,达到和物理分表同样的效果,但操作起来更 简单,不同于物理分表那样使用时还需要指定使用的数据表.对于使用者来说和操作普通表无差别. 二.优势 ...
- element UI rules prop对应关系
- 使用Python玩转阿里云盘
项目地址: https://github.com/foyoux/aligo 这个项目起源于我的一个简单需求, 我有25000个文件, 已经上传了9000个, 但是现在我把这些文件重新整理了, 最后我不 ...
- Windows协议 LDAP篇 - 域用户和计算机用户
域用户 查询域用户 通过SAMR协议查询(net user就是通过这种协议查询的),samr也不是一种专门的协议,是一个RPC接口 在impacket里有个脚本samrdump.py,就是专门调用这个 ...
- Moco框架jar下载
下载地址: https://repo1.maven.org/maven2/com/github/dreamhead/moco-runner/0.10.0/ 选择如下图下载 下载成功即可使用