经典递归问题集锦

转载自:http://blog.csdn.net/u012706811/article/details/50531460

总体来说递归基本可表述成以下类似的结构:

递归调用(参数) {

if (基本情形) {

// ...

// 完成,收工

} else { // 递归情形

// ...

递归调用( 新参数 );

}

}

因此,写递归程序一是明确基本情形,二是找出递归情形。

eg1:求阶乘

   也就是输入一个数,然后求出他的阶乘,例如输入5,则求5!=120

分析: 
   画出示意图如下: 
这里写图片描述 
可以看出基本情形就是1!=1,特殊情形就等于f(n-1),所以程序如下

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">getIndex</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> n) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (n==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//基本情况</span>
        }<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>{
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> n * getIndex(n-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//特殊情况</span>
        }
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

eg2:斐波那契数列

   输入一个数表示斐波那契数列的第几项,然后找出这一项的值

分析: 
这里写图片描述 
可以看出基本情景就是f(2)=1,f(1)=1,特殊情景就是f(n-1)+f(n-2) 
所以程序如下

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">getIndex</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> n) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (n==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>||n==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>) {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//基本情况</span>
        }<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>{
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> getIndex(n-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)+getIndex(n-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//特殊情况</span>
        }
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

eg3:汉诺塔问题

   大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

分析三个柱子分别是ABC,现在要从A移动到C 
当只有一个盘子时,只需要A->C 
当有两个盘子的时候,先A->B,再A->C,再B->C 
当有三个盘子的时候,先把前两个借助C移动到B,然后再把第三个移动到C,剩下两个再如此进行 
当有N个盘子的时候,先把N-1个盘子借助C移动到B,再把第N个移动到C,剩下N-1个盘子,再借助C移动到AN-2个,再把第N-1个盘子移动到C,如此循环 
这里写图片描述 
对于图片又要解释的就是,移动分两步,一步是移动到目标,另一步则是借助一个柱子,移动N-1个到空闲柱子,那基本情况就是当盘子为1的时候,直接移动到目标,代码如下

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">move</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> n,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> from,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> to,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i){
            System.out.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"移动第"</span>+n+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"个盘子从"</span>+from+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"-->"</span>+to+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"--"</span>+i);
    }

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">hanoi</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> n,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> from,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> depand_on,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> to){
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (n==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) {
            move(n, from, to,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//如果只剩最后一个盘子就将盘子移动到指定位置</span>
        }<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
            hanoi(n-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, from, to, depand_on);
            move(n, from, to,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);
            hanoi(n-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, depand_on, from, to);
        }

    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul>

这里写图片描述 
看输入,每动其他盘子,后面必要动第一个盘子,也就是执行N==1这个情况


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值