再议“生成全排列算法”

简介:

看了“白话算法(7) 生成全排列的几种思路(一)”和“白话算法(7) 生成全排列的几种思路(二) 康托展开”。在此,将以前本人推导的全排列算法介绍一下,和广大的网友交流一下。

  以例子说明,用0、1、2、3,四个数组成全排列。

  首先可以知道,这四个数组成的全排列一共有4!=24个。那么给这24个全排列编号,分别为0、1、2……23。再给定一个算法,通过编号计算出一个全排列。本文的目的就是找到这样的算法。

  把所有的全排列列举出来可以发现,0在末位的有6个,1在末位的有6个,等等。

  观察0在末位的六个,分别是

  1、2、3、0

  1、3、2、0

  2、1、3、0

  2、3、1、0

  3、1、2、0

  3、2、1、0

  可以看出这6个全排列,除了末位是0外,前面三个数正好是1、2、3的全排列

  再观察1在末位的六个,分别是

  0、2、3、1

  0、3、2、1

  2、0、3、1

  2、3、0、1

  3、0、2、1

  3、2、0、1

  也可以看出这6个全排列,除了末位是1外,前面三个数正好是0、2、3的全排列

  类似的,末位是2和3的6个全排列,除了末位是一样的以外,前面三个数正好是剩下的三个数的全排列。

  

  于是该问题就可以用下面的步骤来解决。

  1、根据编号确定末位数字

  2、确定末位数字后,获得剩余的数字

  3、对编号适当的处理,得到新的编号

  4、问题演化成除了末位数字后,用新的编号和剩余的数字,计算剩余数字的全排列。

 

  再用一个具体的例子来说明。比方说,用编号13来计算0、1、2、3的一个全排列。

  1、先给这4个数字排好序。是0、1、2、3

  2、计算[13/3!]+1=3,表示末位数是第3个数。注:[X]表示取X的整数部分。

  3、把第3个数和第4个数(未排的最后1个数)交换。此时,数字的顺序是0、1、3、2。蓝色的表示已经排好。

  4、新的编号为13 mod 3!=1

  5、计算[1/2!]+1=1,表示末位数是第1个数。

  6、把第1个数和第3个数(未排的最后1个数)交换。此时,数字的顺序是3、1、0、2。蓝色的表示已经排好。

  7、新的编号为1 mod 2!=1

  8、计算[1/1!]+1=2,表示末位数是第2个数。

  9、把第2个数和第2个数(未排的最后1个数)交换。此时,数字的顺序是3、1、0、2。蓝色的表示已经排好。

  10、因为只剩下一个数,所以编号13对应的全排列就是3、1、0、2

 

  其他的编号计算方法和此一样。

  后面的这个表格就是按照上面的算法得到所有的编号和全排列的关系

A(0) A(1) A(2) A(3) 编号
1 2 3 0 0
2 1 3 0 1
2 3 1 0 2
3 2 1 0 3
1 3 2 0 4
3 1 2 0 5
3 2 0 1 6
2 3 0 1 7
2 0 3 1 8
0 2 3 1 9
3 0 2 1 10
0 3 2 1 11
1 3 0 2 12
3 1 0 2 13
3 0 1 2 14
0 3 1 2 15
1 0 3 2 16
0 1 3 2 17
1 2 0 3 18
2 1 0 3 19
2 0 1 3 20
0 2 1 3 21
1 0 2 3 22
0 1 2 3 23

  

  通过这样的算法,通过指定的编号就能算出一个全排列。

  如果要遍历所有的全排列,则只要遍历编号就能完成。

  如果要随机获得一个全排列,则随机生成一个编号,再计算出全排列就可以了。

 

  具体的代码在我之前的文章“遍历排列的实现——VB2005”中,这里就不重复贴出了。


    本文转自万仓一黍博客园博客,原文链接:http://www.cnblogs.com/grenet/archive/2011/04/29/2032812.html,如需转载请自行联系原作者


相关文章
|
1月前
|
算法 C++ 索引
【算法】——全排列算法讲解
【算法】——全排列算法讲解
|
4月前
|
机器学习/深度学习 存储 算法
【算法训练-回溯算法 一】【排列问题】全排列、全排列II
【算法训练-回溯算法 一】【排列问题】全排列、全排列II
49 0
|
1月前
|
算法 Java
算法-----全排列
算法-----全排列
|
5月前
|
算法
代码随想录算法训练营第二十八天 | LeetCode 491. 递增子序列、46. 全排列、47. 全排列 II
代码随想录算法训练营第二十八天 | LeetCode 491. 递增子序列、46. 全排列、47. 全排列 II
39 0
|
8月前
|
机器学习/深度学习 存储 算法
算法训练Day29|* 491.递增子序列* 46.全排列* 47.全排列 II
算法训练Day29|* 491.递增子序列* 46.全排列* 47.全排列 II
|
10月前
|
自然语言处理 算法
经典算法之——解决全排列问题以及详解
经典算法之——解决全排列问题以及详解
183 0
|
10月前
|
机器学习/深度学习 算法 Python
Python|“套娃”算法-递归算法解决全排列
Python|“套娃”算法-递归算法解决全排列
93 0
|
11月前
|
算法
回溯算法 全排列模板
回溯算法 全排列模板
53 0
|
11月前
|
算法 C++ 容器
C++ vector 容器的全排列算法 next_permutation
C++ vector 容器的全排列算法 next_permutation
123 0
|
11月前
|
算法 前端开发 iOS开发
前端电商 sku 的全排列算法很难吗?学会这个套路,彻底掌握排列组合
前段时间在掘金看到一个热帖 《今天又懒得加班了,能写出这两个算法吗?带你去电商公司写商品中心》,里面提到了一个比较有意思故事,大意就是一个看似比较简单的电商 sku 的全排列组合算法,但是却有好多人没能顺利写出来。有一个毕业生小伙子在面试的时候给出了思路,但是进去以后还是没写出来,羞愧跑路~