Java与算法之(4) - 数字全排列
全排列是指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与算法之(4) - 数字全排列的更多相关文章
- Java实现 蓝桥杯VIP 算法训练 判定数字
算法训练 判定数字 时间限制:1.0s 内存限制:512.0MB 编写函数,判断某个给定字符是否为数字. 样例输入 9 样例输出 yes import java.util.Scanner; publi ...
- 史上最全的java随机数生成算法分享(转)
这篇文章主要介绍了史上最全的java随机数生成算法,我分享一个最全的随机数的生成算法,最代码的找回密码的随机数就是用的这个方法 String password = RandomUtil.generat ...
- JAVA经典算法40题及解答
JAVA经典算法40题 [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 1.程序分 ...
- Java基础算法集50题
最近因为要准备实习,还有一个蓝桥杯的编程比赛,所以准备加强一下算法这块,然后百度了一下java基础算法,看到的都是那50套题,那就花了差不多三个晚自习的时间吧,大体看了一遍,做了其中的27道题,有一些 ...
- Java经典算法四十例编程详解+程序实例
JAVA经典算法40例 [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 1.程 ...
- JAVA经典算法40题
1: JAVA经典算法40题 2: [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 3 ...
- Java与算法之(13) - 二叉搜索树
查找是指在一批记录中找出满足指定条件的某一记录的过程,例如在数组{ 8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15 }中查找数字15,实现代码很简单 ...
- Java 密码学算法
Java 密码学算法 候捷老师在< 深入浅出MFC 2e(电子版)>中引用林语堂先生的一句话: 只用一样东西,不明白它的道理,实在不高明 只知道How,不知道Why,出了一点小问题时就无能 ...
- java排序算法之冒泡排序(Bubble Sort)
java排序算法之冒泡排序(Bubble Sort) 原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一趟:首先比较第1个和第2个数 ...
随机推荐
- iOS开发之JSON转PLIST(把存储json格式的文件转换成plist文件)
p.p1 { margin: 0.0px 0.0px 0.0px 60.0px; font: 16.0px "PingFang SC"; color: #586e75 } p.p2 ...
- ligerUI---下拉框(Combobox)
写在前面: 突然发现,从刚开始对ligerUI的抵触,觉得都没有接触过,也不会,到现在,感觉ligerUI的一些组件还是挺好用的,大概日久生情吧.嘻嘻~~~,下拉框是常用的一个组件,在之前的博客中也写 ...
- iOS 环信集成项目应用
环信iOS端3.0版本集成记录--聊天界面篇 环信离线推送证书... 1,环信处在后台的时候,消息的接收与推送 离线发推送 配置属性 EMCallOptions *options = [[EMClie ...
- scala写算法-用小根堆解决topK
topK问题是指从大量数据中获取最大(或最小)的k个数,比如从全校学生中寻找成绩最高的500名学生等等. 本问题可采用小根堆解决.思路是先把源数据中的前k个数放入堆中,然后构建堆,使其保持堆序(可以简 ...
- ucore lab1 bootloader学习笔记
---恢复内容开始--- 开机流程回忆 以Intel 80386为例,计算机加电后,CPU从物理地址0xFFFFFFF0(由初始化的CS:EIP确定,此时CS和IP的值分别是0xF000和0xFFF0 ...
- 统计nginx单个IP访问日志并获取IP来源
#!/usr/bin/env python #coding=utf-8 import requests from urllib2 import urlopen # import lxml.html f ...
- 自己动手写把”锁”之---JMM和volatile
一.JAVA内存模型 关于Java内存模型的文章,网上真的数不胜数.在这里我就不打算说的很详细.很严谨了.只力求大家能更好的理解和运用,为后边的技术点做铺垫. 内存模型并不是Java独有的概念,而 ...
- String 转化成java.sql.Date和java.sql.Time
String类型转换成java.sql.Date类型不能直接进行转换,首先要将String转换成java.util.Date,在转化成java.sql.Date 请点击---> java架构 ...
- ssh简明安全规划
禁止使用口令只允许使用密钥建立 SSH 连接 1.创建 SSH KEY 使用ssh-keygen生成一个密钥对,并且将公钥注册到服务器的 $HOME/.ssh/authorized_keys 文件. ...
- 几种加密算法的java实现包括MD5、RSA、SHA256
SHA加密: package com; import java.security.MessageDigest;import java.security.NoSuchAlgorithmException ...