Java与算法之(4) - 数字全排列

原创 2016年08月31日 16:29:05

全排列是指n个数(或其他字符)所有可能的排列顺序,例如1 2 3三个数字的全排列是

1 2 3 
1 3 2 
2 1 3 
2 3 1 
3 1 2 
3 2 1 

那么问题来了,任意输入一个大于1的数字n,列出1-n这n个数字的全排列。

如果尝试手动列举一下1 2 3的全排列,会发现通常我们会在头脑中制定好规则,并按照既定规则进行枚举,从而得到所有排列。

在这里我们制定的规则是:

(想象我们手里拿了3个数字,地上有A、B、C三个空位)

1)在每一个空位前,都按照1->2->3的顺序尝试放下一个数字,如果该数字已经放下则尝试下一个

2)每放下一个数字后向后移动一格,然后重复1->2->3的尝试

3)如果当前位置没有新的可能性,取回当前位置的数字并左移一格从新尝试

按上面规则很容易推算出第一种排列是1 2 3

取回3,返回B位置,取回2,然后按1->2->3尝试,发现可以放下3,右移到C,尝试后放下2,得到1 3 2

接下来必须返回到A的位置才有新的可能性,此时已经取回所有数字,按规则放下2,移到B,放下1,移到C,放下3,得到2 1 3

。。。

下面来看实现的代码:

public class Permutation {

	private int max;
	private int[] array;
	private int[] hold;
	
	public Permutation(int max) {
		this.max = max;
		array = new int[max + 1];
		hold = new int[max + 1];
	}
	
	public void permute(int step) {
		if(step == max + 1) {
			for(int i = 1; i <= max; i++) {
				System.out.print(array[i] + " ");
			}
			System.out.println();
			return;  //返回上一步, 即最近一次调用permute方法的后一行
		}
		//按照1->2->3->...->n的顺序尝试
		for(int num = 1; num <= max; num++) {
			//判断是否还持有该数字
			if(hold[num] == 0) {
				array[step] = num;
				hold[num] = 1;
				//递归: 右移一格重复遍历数字的尝试
				permute(step + 1);
				//回到当前位置时取回当前位置数字
				hold[num] = 0;
			}
		}
	}
	
	public static void main(String[] args) {
		Permutation fa = new Permutation(3);
		fa.permute(1);
	}
}

运行输出

1 2 3 
1 3 2 
2 1 3 
2 3 1 
3 1 2 
3 2 1 

我们用一个伪时序图来帮助理解递归调用的执行过程


顺便说一句,全排列问题还有多种算法,本文中使用的是深度优先算法的模型。

版权声明:欢迎转载, 转载请保留原文链接。

java递归实现N个数全排列输出

  • 2007年11月20日 22:57
  • 2KB
  • 下载

全排列的四种生成算法

1.字典序法   字典序法中,对于数字1、2、3......n的排列,不同排列的先后关系是从左到右逐个比较对应的数字的先后来决定的。例如对于5个数字的排列 12354和12345,排列12...
  • gaixm
  • gaixm
  • 2015年10月20日 21:00
  • 1604

Java 实现m个数全排列组合以及从M中选取N个数(有序)

(1)全排列组合的递归规律: 集合s的全排列组合 all(s)=n+all(s-n);其中n为已经取出的集合 以集合 s={1,2,3}为例,则s的全排列组合为all(s)={1}+all({2,...
  • leixingbang1989
  • leixingbang1989
  • 2015年08月18日 22:22
  • 8643

java中全排列的生成算法汇总

全排列的生成算法就是对于给定的字符集,用有效的方法将所有可能的全排列无重复无遗漏地枚举出来。任何n个字符集的排列都可以与1~n的n个数字的排列一一对应,   因此在此就以n个数字的排列为例说明排列的生...
  • qfikh
  • qfikh
  • 2016年08月29日 09:41
  • 4732

一次搞懂全排列——LeetCode四道Permutations问题详解

LeetCode中与Permutations相关的共有四题:   31. Next Permutation   46. Permutations   47. Permutations II  ...
  • Jacky_chenjp
  • Jacky_chenjp
  • 2017年03月26日 17:52
  • 3729

[java]冒泡算法:让数字从小到大排序

package org.company.project.test; import java.util.Arrays; import java.util.Random; public class Arr...
  • wahxsm
  • wahxsm
  • 2015年06月30日 12:33
  • 4198

java数组中数字从小到大排序——冒泡排序法

定义一个int 类型的数组,并将其中的数从小到大的排列。 思路:从数组中拿出两个数来进行比较并保留最小的值来和数组中的其他值进行比较,得到最小值,并把他放到第一位(i 循环一次,j 进行了一次所有值...
  • eclipse_yin
  • eclipse_yin
  • 2016年04月06日 20:25
  • 9691

Java简单算法——数据全排列

题目: 将1-5,5个数字进行全排列,并输出共有多少种方案? import java.util.Arrays; /* 将1-5,5个数字进行全排列,并输出共有多少种方案 */ pu...
  • Roger1279
  • Roger1279
  • 2017年04月07日 14:01
  • 185

全排列数的生成

这学期好忙,整个人都变懒了。。coursera上的课程作业只来得及更新到github上,希望自己以后看着注释还能记得怎么做。。。得空把上学期的一些作业放这里。 【问题描述】输入整数N( 1 ...
  • Jason_Ranger
  • Jason_Ranger
  • 2016年09月20日 13:21
  • 1650

数组的全排列

1.问题背景学过数学的人都知道,全排列的意思是什么。现在如何用计算机的编程语言实现数组的全排列呢?数组的全排列可用于求解八皇后问题,具体参见:全排列解决八皇后问题。与此同时,全排列经常会出现在笔试或者...
  • K346K346
  • K346K346
  • 2016年04月15日 00:46
  • 6503
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java与算法之(4) - 数字全排列
举报原因:
原因补充:

(最多只允许输入30个字)