递归-猴子吃桃

文章讲述了如何使用递归方法解决猴子摘桃问题,指出初始递归代码中的后置自减导致无限循环,通过改变递归终止条件为前置自减解决了问题,最终成功求解第10天剩余1桃子时第一天摘的桃子数量。

问题:猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个:第二天早上将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半多一个,到第10天早上想再吃时,只剩下一个桃子了。问第一天共摘了多少桃子?

这道题我用递归,我的方法不限制是第几天(即可以是第1,2,3,...,10...天剩余1个桃子)

开始的时候用下面的代码

public int monkey_peach(int days){
    if(days==1)
        return 1;
    return (monkey_peach(days--)+1)*2;
}

报错:Exception in thread "main" java.lang.StackOverflowError

后来发现问题:

递归调用的终止条件是 days==1,但在递归调用中,我使用了后置自减运算符 days--,它会先将 days 的值传递给函数,然后再将 days 减一。这意味着在下一次递归调用时,传入的参数仍然是原始值,而不是减一后的值,导致递归无法终止。

所以我改了一下:

public int monkey_peach(int days){
    if(days==1)
        return 1;
    return (monkey_peach(--days)+1)*2;
}

运行成功!

### 猴子问题递归实现 猴子问题是经典的递归问题之一,描述如下: 某只猴子第一了一些桃子,之后每掉一半加一个,到了第`n`,发现只剩下一个桃子。任务是求出第一了多少个桃子。 该问题可以通过**逆向思维**来解决,即从最后一倒推到第一,利用递归函数实现。 #### 递归思路 - **终止条件**:当`day == n`时,只剩下一个桃子,返回1- **递归公式**:第`day`桃子数等于第`day+1`桃子数加上1之后乘以2。 - **递归调用**:函数调用自身计算`day+1`桃子数。 #### Java 实现代码示例 ```java public class MonkeyEatPeach { public static void main(String[] args) { int n = 10; // 假设第10只剩下一个桃子 int initialPeaches = monkeyPeaches(1, n); if (initialPeaches != -1) { System.out.println("第一桃子数为: " + initialPeaches); } else { System.out.println("输入数无效"); } } public static int monkeyPeaches(int day, int n) { if (day == n) { return 1; } else if (day < n) { return (monkeyPeaches(day + 1, n) + 1) * 2; } else { return -1; // 无效输入 } } } ``` #### 代码说明 - `monkeyPeaches` 是递归方法,用于计算第`day`桃子数。 - 通过递归调用,从最后一开始逐步推算出第一桃子数。 - 如果输入的数不合法(如`day > n`),函数返回`-1`表示错误。 #### 时间复杂度与优化 - 当前递归实现的时间复杂度为 *O(n)*,空间复杂度也为 *O(n)*,因为递归调用栈的深度取决于数`n`。 - 如果需要优化性能,可以考虑使用**记忆化递归**或**动态规划**来避免重复计算。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值