递归问题以及斐波那契数列(蓝桥1534)

递归的介绍

1 递归的概念

函数调用自身来解决问题

2 递归的关键要素

(1)终止条件:直接解决绩效规模问题的方法

(2)递归表达式:用于解决一个更小的子问题,再将子问题的答案合并成为当前问题答案

递归如何实现

1 实现过程

(1)将一个复杂问题分解为更小的、相似的问题

(2)通过函数自身调用自身来解决这些更小的问题

(3)通过递归终止条件来结束递归

2 细节

(1)确保有递归出口,避免无线递归,可能导致运行错误RE、超内存MLE、超时TLE。

(2)考虑分界条件,递归出口可能不止一个

(3)避免不必要的重复计算

3 递归函数基本结构

返回类型 函数名(参数列表){
    if(满足终止条件){      //基本情况(递归终止条件)
        //返回终止条件下的结果
    }else{                  //递归表达式
        //降温贴分解为规模更小的子问题
        //递归调用解决子问题
        //返回子问题结果
    }
}

递归和循环的比较

递归循环
  • 优点

    • 递归代码通常更简洁、更易于理解,特别是对于那些自然递归的问题(如树和图的遍历、分治算法等)。
    • 递归可以简化代码,减少重复代码的编写。
    • 递归可以解决一些循环难以表达的问题,如快速排序、归并排序等。
  • 缺点

    • 递归可能会导致较高的内存消耗,因为每次递归调用都会在调用栈上增加一层。
    • 递归可能会导致栈溢出错误,特别是在处理大量递归调用时。(栈空间一般8MB,递归层数不超过1E6层)
    • 递归的性能通常低于循环,因为函数调用自身涉及额外的开销。
  • 优点

    • 循环通常比递归更高效,因为它们不需要函数调用的开销。
    • 循环不会导致栈溢出错误,因为它们不涉及额外的栈帧。
    • 循环可以处理大量重复操作,而不会像递归那样消耗大量内存。
  • 缺点

    • 循环代码可能比递归代码更复杂,特别是在处理复杂逻辑时。
    • 循环可能不如递归直观,特别是在处理自然递归的问题时。
    • 循环可能难以表达某些算法,如树的深度优先搜索等。

 部分情况下,递归和循环可以相互转化

例题

1 斐波那契数列

定义:F(0) = 0  F(1) = 1   对于 n > 1,F(n) = F(n-1) + F(n-2)

求斐波那契数列的第n项

int fibonacci(int n) {
    if (n <= 1) {
        return n;
    } else {
        return fibonacci(n - 1) + fibonacci(n - 2);
    }
}

为了减小空间复杂度,我们使用带备忘录的递归:

long long dp[n];
long long fib(int n){
    if(dp[n]) return dp[n];
    if(n<=2) return 1;
    else return dp[n]=(fib(n-1)+fib(n-2));//dp[n]的记录免去重复计算
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值