Recursion 递归

问题

排列ssnn个成员[x1,x2,,xn][x_1,x_2, \dots ,x_n],每个成员可以选取[1,2,,m][1,2, \dots ,m]mm种值。例如当n=3,m=3n = 3, m = 3时,排列ss有以下情况:

[1,1,1][2,1,1][1,2,1][1,1,2][2,2,1][2,1,2][1,2,2][2,2,2][3,1,1][1,3,1][1,1,3][3,3,1][3,1,3][1,3,3][3,3,3][2,3,1][3,2,1][2,1,3][3,1,2][1,2,3][1,3,2][2,2,3][2,3,2][3,2,2][3,3,2][3,2,3][2,3,3]\begin{matrix} [1,1,1] \\ [2,1,1] \\ [1,2,1] \\ [1,1,2] \\ [2,2,1] \\ [2,1,2] \\ [1,2,2] \\ [2,2,2] \\ [3,1,1] \\ [1,3,1] \\ [1,1,3] \\ [3,3,1] \\ [3,1,3] \\ [1,3,3] \\ [3,3,3] \\ [2,3,1] \\ [3,2,1] \\ [2,1,3] \\ [3,1,2] \\ [1,2,3] \\ [1,3,2] \\ [2,2,3] \\ [2,3,2] \\ [3,2,2] \\ [3,3,2] \\ [3,2,3] \\ [2,3,3] \end{matrix}

给定n,mn, m的值,用Recursion求排列ss的所有情况。

解法

BruteForce存在一个问题,外围for循环的数量固定,无法随着nn的改变而改变。递归可以解决这个问题。

假设排列ss的长度从00增长到nn。初始化时令排列为空s=[]s = []

(1)(1) 将排列ss的长度增加到11,第11个元素(唯一的元素)x1x_1mm种选择,即长度为11的排列ssmm个排列组合:

[11][21][m1]\begin{matrix} [ 1_1 ] \\ [ 2_1 ] \\ \cdots \\ [ m_1 ] \end{matrix}

(2)(2) 将排列ss的长度增加到22,得到s=[x1,x2]s = [x_1,x_2],元素x2x_2的选择可以看作在第(1)(1)步的每个选择的基础上继续选择。对于[11][1_1]可以得到mm个排列组合:

[11,12][11,22][11,m2]\begin{matrix} [ 1_1,1_2 ] \\ [ 1_1,2_2 ] \\ \cdots \\ [ 1_1,m_2 ] \end{matrix}

对于[21][2_1]可以得到mm个排列组合:

[21,12][21,22][21,m2]\begin{matrix} [ 2_1,1_2 ] \\ [ 2_1,2_2 ] \\ \cdots \\ [ 2_1,m_2 ] \end{matrix}

显然对于第(1)(1)步的mm个排列组合,每个都可以产生mm个排列组合,因此第(2)(2)步共有m2m^2个排列组合。由此可知,第(n)(n)步后可以得到mnm^n个排列组合。

根据乘法定理可知,对于成员数量为nn,每个成员有mm个值的排列ss,遍历所有排列组合的时间复杂度O(mn)O(m^n)

源码

Recursion.h

Recursion.cpp

测试

RecursionTest.cpp

Last updated