美文网首页
从N-1到N——理解递归的一种思路

从N-1到N——理解递归的一种思路

作者: zhizhuwang | 来源:发表于2017-01-24 22:10 被阅读43次

从面向过程中的循环控制语句,转变到函数式编程中无处不在的递归,往往需要有一个适应的过程。

本文以求一个列表的全排列为例,描述一种从数学归纳法的角度来理解递归的方式,使用这种思路可以更加容易地写出正确的递归来。

数学归纳法的原理在于:首先证明在某个起点值时命题成立,然后证明从一个值到下一个值的过程有效。同样地,如果我们能求得某一个起点的值f(1),那么,只要我们知道如何在f(N-1)的基础上求得f(N),递归的问题就可以解决了。以此为思路,递归语句就不那么难理解了,也不那么难写了。

以求一个列表的全排列为例说明这个过程。比如,对于[1,2,3]这样的序列,要求返回 [1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]

递归的起点是只有一个元素的情况,也就是:
perms([X]) -> [X];

对于列表L中的每一个元素X,如果除X之外的子列表[L--X]的全排列已经求出来了,那么整个列表L的全排列就可以求出来了;它们之间的关系是:把X添加在[L--X]的全排列中每一个结果的头部。

例如,如果X1,除了1之外的子列表[L--X]的全排列为[ [2,3], [3,2] ],那么把1加到每个结果元素的头部,得到[ [1,2,3], [1,3,2] ];同理,分别将X对应为23,执行相同的过程就可以得到最终的结果[ [1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1] ]

用Erlang代码表达就是这样:

perms([X]) -> [X];
perms(L) ->  [ [X|T] || X<-L, T<-perms(L--[X])].

对于这个问题,还可以有另外一种解决的思路。对于一个列表L,如果除第一个元素H之外的子列表的全排列集已经求出来了,再将H插入到此集中每一个元素的每一个位置就可以了。

例如:[1,2,3]的子列表[2,3]的全排列是[ [2,3], [3,2] ],则将1插入 [2,3][3,2]中的每一个位置,分别得到[ [1,2,3],[2,1,3],[2,3,1] ][ [1,3,2], [3,1,2],[3,2,1] ],然后将这两个列表合并即可得到最终的结果。
用代码表示就是:

perms([X]) -> [X];
perms([H|T]) -> lists:append([interleave(H, R) || R <- perms(T)]).

其中interleave的实现如下:

interleave(X, []) -> [X];
interleave(X, [H|T]) ->
        [X|[H|T] | [H|R] || R <- interleave(X, T)].

相关文章

  • 从N-1到N——理解递归的一种思路

    从面向过程中的循环控制语句,转变到函数式编程中无处不在的递归,往往需要有一个适应的过程。 本文以求一个列表的全排列...

  • 8.23leetcode刷题汇总

    算法思路:递归设计的2种思路:1.假设f(n-1)成立,利用f(n-1)和element(n)找到f(n)2.先设...

  • 笔试刷题-腾讯2018-08-18

    题目描述: 思路如下: 用递归思想找规律即可f(n-1)表示n-1个的序列产生f(n)先顺序遍历f(n-1)在头部...

  • 70. Climbing Stairs

    经典递归,dp[i] = dp[i-1]+dp[i-2],从0 算到n-1 ,返回dp[n-1] dp[0] = ...

  • 剑指offer 07 跳台阶

    题目: 思路: 1.递归方法:满足斐波那列数列,return dp[n-1] + dp[n-2];不建议这样做,这...

  • 算法二

    递归表达式 n! = n*(n-1)! (0!=1) 递归经常需要初始条件以及递归表达式。 从低端构造递归,...

  • 大数阶乘(N! Plus)问题

    1.解题思路 将正整数N从1到N逐位相乘,即1 * 2 * 3...... * (N-1) * N。每次相乘后的值...

  • java中的递归与迭代

    1.递归 如这个阶乘函数:n!=n*(n-1)*(n-2)*...*1计算阶乘的方法有很多。 一种方法是n!=n*...

  • 递归与非递归求阶乘

    递归求5!: 当n>1时,a=n(n-1)n(-2)2 当n=1时,结果为a1。 非递归求5!

  • 递归在实际中的应用与思考

    递归的三种表现形式 定义是递归的:例:阶乘函数的定义——n! = 1;n = 0时n! = n * (n-1)! ...

网友评论

      本文标题:从N-1到N——理解递归的一种思路

      本文链接:https://www.haomeiwen.com/subject/naqtittx.html