博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【HDU 2013 猴子吃桃子】 尾递归与迭代
阅读量:6958 次
发布时间:2019-06-27

本文共 1260 字,大约阅读时间需要 4 分钟。

大一时的一道C语言练习题,可作为递归和尾递归转迭代的范例。HDU 2013 

题意:猴子摘了sum个桃子,从第1天开始,每天吃掉剩余桃子的一半多一个,第n天时只剩1个桃子,求sum值。

分析:设第 i 天在开吃之前所剩的桃子数为sum(i),第 i 天要吃掉的桃子数为f(i),

则问题可表示为:已知sum(n)=1 和如下两个关系式:

  f(i) = sum(i)/2 + 1      (1)

  sum(i+1) = sum(i) - f(i)    (2)

  求sum(1)。

求解:(1)(2)式联立,可得递推式sum(i+1) = 2*sum(i) + 2。加上递归基sum(n)=1,可直接写出如下递归函数:

1 int sum(int x){2     if(x==n) return 1;3     return 2*sum(x+1) + 2;4 }

在主函数中调用sum(1)即可得答案。

上面的递归函数属于尾递归(递归调用在最后一步),可以比较直观地转成迭代形式。只需从递归基出发进行n-1次迭代,即可得到同样的结果。代码如下:

1 ans=1;2 int i=1;3 while(i++ < n){4     ans = 2*ans + 2;5 }

这道题的迭代相比递归,省去了n-1层调用栈,空间复杂度从O(n)降到O(1),时间复杂度仍为线性的O(n)。

 

下面再来看一道尾递归转迭代的问题:Fibonacci数。

递推式 fib(n) = fib(n-1) + fib(n-2),递归基fib(0)=0, fib(1)=1。可写出如下递归函数:

1 int fib(int n){2     if(n==0) return 0;3     if(n==1) return 1;4     return fib(n-1)+fib(n-2);5 }

通过递归树分析,这一递归版包含了很多的重叠子问题,时间复杂度为O(2n),空间复杂度O(n)。

不过它同样属于尾递归,因而可以较方便地转为迭代版:

1 int fibI(int n){2     int f=0, g=1;     // fib(0), fib(1)3     int i=1;4     while(i++ < n){5         g = g + f;     // fib(n) = fib(n-1) + fib(n-2)6         f = g - f;     // fib(n-1) = fib(n) - fib(n-2)7     }8     return g; // fib(n)9 }

这里的两个变量f, g在每次迭代后都保存相邻两项fibonacci数,二者滚动向前(图片来自MOOC: TsinghuaX: 30240184X 数据结构(2015秋)),直至抵达最终的fib(n)。

此迭代版本只包含一个线性的while循环,因此时间复杂度为O(n),仅用两个变量暂存,故空间复杂度为O(1)。

转载地址:http://ktqil.baihongyu.com/

你可能感兴趣的文章
VMware vCenter VMotion 详解
查看>>
对象数组转化DataSet并导出到文本
查看>>
搜索搜索引擎常用的18大学术搜索引擎
查看>>
struts2--java.lang.IllegalAccessException: Class ognl.OgnlRuntime can not access a member of
查看>>
sicp第二章部分习题解答
查看>>
Modern Objective-C
查看>>
2013 HTML5 峰会,HTML5 守望者的盛宴
查看>>
PD的CDM模型中的三种实体关系
查看>>
All you should know about NUMA in VMware!
查看>>
java 版本SQLHelper
查看>>
Hyper-V中的VM如何使用Pass-through Disk
查看>>
vim基础
查看>>
Ubuntu下配置jdk及maven等方法
查看>>
CShopDialog类
查看>>
lib 和 dll 的区别、生成以及使用详解
查看>>
python Genarator函数
查看>>
Citrix 服务器虚拟化之十 Xenserver高可用性HA
查看>>
关于ADB server didn't ACK * failed to start daemon *的问题
查看>>
Java菜鸟学习笔记--数组篇(二):数组实例&args实例
查看>>
黑马程序员—Java动态代理详解
查看>>