递归详解(一)全排列问题 数据结构-算法解析-浙大-PAT

递归——全排列问题(Full Permutation)

​ 废话少说,首先看定义:

全排列(Full Permutation),一般把1~n这n个整数按某个顺序摆放的结果称为这n个整数的一个排列 ,而全排列指这n个整数能形成的所有排列。例如对1、2、3这三个整数来说, (1, 2, 3)、(1, 3, 2)、(2, 1, 3)、(2, 3, 1)、(3, 1, 2)、(3, 2, 1)就是1~3的全排列

​ 现在需要实现按字典序从小到大的顺序输出 1~n 的全排列,其中 (a1, a2, …, an) 的字典序小于 (b1, b2, …, bn) 是指存在一个 i ,使得 a1=b1, a2=b2, …, a(i-1) = b(i-1)、ai<bi 成立。因此上面n=3的例子就是按字典序从小到大的顺序给出的。

​ 按字典序排列用大白话的意思就是:任取排列结果中的两个元素作比较,例如(2, 1, 3)和(2, 3, 1),两个元素的第一位相等都是2(比较下一位),第二位 1 < 3,所以按从小到大的顺序排列时, (2, 1, 3)一定排在(2, 3, 1)前面。

​ 用递归的角度去考虑,如果把问题描述成

”输出1~n这n个整数的全排列“

​ 那么它就可以被分为若干个子问题:

”输出以1开头的全排列“、”输出以2开头的全排列“ … ”输出以n开头的全排列“。

在实现代码前,我们需梳理一下重要逻辑

  1. 我们需要一个int型数组 P, 来存放当前的排列;
  2. 排列中的元素不能重复,例如1~3的全排列,是不能出现(1,2,2)这样的元素的,每个数字能且仅能出现一次。于是我们可以设定一个bool型的数组 Table[x],数组的下标代表当前的数字,默认值为false,当整数x已经在当前排列中使用过的时候,我们就将 Table[x] 的值设置为true。
  3. 当我们按顺序往P的第1位到第n位中填入数字的时候,不妨假设当前已经填好了P[1] ~ P[index-1],正准备填P[index]。显然我们需要for循环遍历1~n,来确定当前的数字x是否在已经枚举的数字中出现过(即Table[x] == false)。若出现过,我们就跳过这个数字去看下一个数字Table[x+1],若没有出现过,就把他填入P[index],同时将Table[x]的值置为true,然后进入递归去处理第index+1位;当排列的全部递归完成时,再将Table[x]的所有值还原为false,以便下一次for循环的判断。
  4. 在递归进行的最后的时候,我们需要规定一个跳出的边界的条件。当P的index到达 n+1 时,说明P的第1~n位都已经填好了,此时便可跳出递归。

如果你已经理解了上述的逻辑推理,可以试着自己先用代

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值