从爬楼梯到算斐波那契,我终于弄懂了递归和动态规划这俩 "磨人精"

最近在代码界摸爬滚打,总被两个词按在地上摩擦 ------ 递归和动态规划。这俩货就像数学题里的 "小明",天天换着花样折磨人,今天就来好好扒一扒它们的底裤。

递归:自己调自己的 "套娃大师"

递归这东西,说白了就是函数自己喊自己的名字。就像小时候问妈妈 "我从哪来的",妈妈说 "你是妈妈生的",再问 "妈妈从哪来的",妈妈说 "外婆生的"... 一直问到祖宗十八代,这就是递归的精髓 ------ 找规律 + 找出口。

比如算个阶乘,用递归(时间复杂度过高)写出来是这样:

js 复制代码
function mul(n){

   if(n === 1){ // 出口:问到祖宗了

       return 1

   }

   return n * mul(n-1) 

}

这代码简洁得像诗,但算个斐波那契数列就露馅了。那个 1,1,2,3,5,8... 的数列,递归写法看着简单:

递归的 "中年危机":重复计算让 CPU 原地冒烟

js 复制代码
function fb(n){

   if(n === 1 || n === 2){

       return 1

   }

   return fb(n-1) + fb(n-2)

}

这代码算个 n=10 还行,要是算 n=40,能让你喝杯咖啡回来还没出结果。就像你查快递单号,每次都要从快递员刚取件的时候查起,哪怕昨天刚查过。

给递归装个 "备忘录":记忆化搜索救场

比如爬楼梯问题:一次能爬 1 或 2 阶,到第 n 阶有几种走法?

后来我灵机一动,给递归加了个小本本(数组 f):

js 复制代码
const f = []
var climbStairs = function (n) {
    if (n === 1 || n === 2) {
        return n
    }
    if (f[n] === undefined) { // 查小本本,没记过才计算
        f[n] = climbStairs(n - 1) + climbStairs(n - 2)
    }
    return f[n]
};

这招叫 "记忆化搜索"(提效),相当于把算过的结果记在通讯录里,下次直接拨号不用重新查号。

后来才发现,这代码就像给老年机装了智能手机的通讯录 ------ 思路对但效率不够。全局数组 f 在多组测试用例下会残留历史数据,而且递归调用本身就有函数栈的开销,n 太大时还是扛不住。

彻底换个活法:动态规划的 "自底向上" 哲学

  • 站在已知的角度,通过已知来定位未知 最后改用纯动态规划找到动态方程)写法,直接逆袭:
js 复制代码
var climbStairs = function (n){
    const f = []
    // 先搞定已知的1楼和2楼
    f[1] = 1
    f[2] = 2
    // 从3楼开始往上爬,每步都踩在前人的肩膀上
    for(let i = 3;i<=n;i++){
        f[i] = f[i-1] + f[i-2]
    }
    return f[n]
 }

这思路就像盖楼,从 1 层开始一层层往上盖,每一层的建材都直接用前两层的,根本不用回头看。没有递归的函数调用开销,也没有重复计算,效率直接拉满。

总结:三种写法的生存现状

写法 特点 适合场景
纯递归 代码简洁如诗 理解思路用,n≤30
记忆化搜索 加了缓存的递归 教学演示,n≤1000
动态规划 自底向上迭代 实际开发,n多大都不怕

总结:什么时候该套娃,什么时候该记笔记?

  • 递归适合简单问题或调试时用,写起来爽,但容易重复劳动

  • 动态规划适合复杂问题,虽然前期要多写几行,但跑起来飞快

  • 记住:所有动态规划问题,先建个空数组当小本本准没错

现在终于明白,递归是浪漫的诗人,只顾优雅不管效率; 动态规划是务实的会计,每一笔账都记得清清楚楚。 下次再遇到这俩货,我可不会再被它们忽悠了!

相关推荐
回眸&啤酒鸭1 小时前
【回眸】OpenSwarm 多智能体协作系统实战指南
大数据·前端·人工智能
用户69371750013842 小时前
2026,程序员的时代拐点到了
android·前端·后端
大龄秃头程序员2 小时前
一次 iBeacon + BLE 无感解锁方案的实现记录
前端
小兔子2 小时前
Python 的 GIL 与 free-threading:3.13 之后「去 GIL」走到哪一步了
前端
IT_陈寒2 小时前
SpringBoot自动配置差点让我加班到凌晨
前端·人工智能·后端
时间的拾荒人2 小时前
Qt 界面优化:绘图详解 —— 从基础图形到图片处理
开发语言·qt·面试
guslegend3 小时前
脚手架原理与本地调试:从 bin 软链接到 npm link
前端·npm·node.js·脚手架·前端工程化
小宋10213 小时前
A2UI从零实战:Agent安全生成交互界面与事件回传
javascript·人工智能·安全·交互
沐言人生4 小时前
又一个神级考公脑库-22,375篇真题终于按考点整理了
后端·面试
大包子4 小时前
structuredClone vs lodash.cloneDeep:核心差异与选型指南
javascript·vue.js