跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava算法

动态规划入门:斐波那契模型与经典例题

动态规划解题模版包含状态表示、转移方程、初始化、填表顺序和返回值五个要素。文章涵盖第 N 个泰波那契数、三步问题、最小花费爬楼梯及解码方法等经典例题,提供 Java 代码实现及空间复杂度优化思路,帮助理解线性 DP 模型的应用。

日志猎手发布于 2026/3/28更新于 2026/10/2592 浏览
动态规划入门:斐波那契模型与经典例题

一、动态规划解题模版

  1. 状态表示:一般创建一维数组 dp,把 dp 表填满,其中的某一个值就是结果。状态表示指 dp 表中元素的含义。 1.1. 来源:题目要求、经验 + 题目要求,分析问题的过程中的重复子问题
  2. 状态转移方程:dp[i] = ?
  3. 初始化:保证根据状态转移方程填表时不越界
  4. 填表顺序:为了填写当前状态的时候,所需要的状态已经计算过了
  5. 返回值:题目要求 + 状态表示

二、第 N 个泰波那契数

题目:第 N 个泰波那契数

题目描述:第四个数是前三个数的和,第一二三个数定为 0 1 1,返回第 n 个数。

题目解析:

解题思路:

  1. 状态表示:dp[i] 表示第 i 个泰波那契数
  2. 状态转移方程:dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3]
  3. 初始化:dp[0] = 0, dp[1] = 1, dp[2] = 1
  4. 填表顺序:顺序从左向右填表即可
  5. 返回值:dp[n]

解题代码:

// 时间复杂度:O(N)
// 空间复杂度:O(N)
class Solution {
    public int tribonacci(int n) {
        if (n < 3) return n == 0 ? 0 : 1;
        int[] dp = new int[n + 1];
        dp[0] = 0;
        dp[1] = dp[2] = 1;
        for (int i = 3; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
        }
        return dp[n];
    }
}

空间优化:只创建长度为三的数组即可:

// 时间复杂度:O(N)
// 空间复杂度:O(1)
  {
       {
         (n < )  n ==  ?  : ;
        [] dp =  []{, , };
         (   ; i <= n; i++) {
               dp[];
            dp[] = dp[];
            dp[] = dp[];
            dp[] = tmp + dp[] + dp[];
        }
         dp[];
    }
}
class
Solution
public
int
tribonacci
(int n)
if
3
return
0
0
1
int
new
int
0
1
1
for
int
i
=
3
int
tmp
=
0
0
1
1
2
2
0
1
return
2

三、面试题 08.01. 三步问题

题目:面试题 08.01. 三步问题

题目描述:每次上楼梯有三个选择:1、2、3,返回走到第 n 阶梯有多少种走法。

题目解析:

解题思路:

  1. 状态表示:dp[i] 表示第 i 阶的上楼方式种类数
  2. 状态转移方程:dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3]
  3. 初始化:dp[0] = 1, dp[1] = 1, dp[2] = 2(小孩有 3 种走法,那么小孩的上一个台阶的可能就是 i-1,i-2,i-3)
  4. 填表顺序:顺序从左向右填表即可
  5. 返回值:dp[n]

解题代码:

// 时间复杂度:O(N)
// 空间复杂度:O(N)
class Solution {
    public int waysToStep(int n) {
        if (n < 3) return n;
        int[] dp = new int[n + 1];
        dp[0] = dp[1] = 1;
        dp[2] = 2;
        for (int i = 3; i <= n; i++) {
            dp[i] = ((dp[i - 1] + dp[i - 2]) % 1000000007 + dp[i - 3]) % 1000000007;
        }
        return dp[n];
    }
}

四、746. 使用最小花费爬楼梯(easy)

题目:746. 使用最小花费爬楼梯(easy)

题目描述:给我们一个 cost 数组,表示走出这一个台阶需要的花费,可以选择第一步从 cost[0] 还是 cost[1] 开始。让我们返回到达楼顶的最小总花费。

题目解析:

解题思路:

  1. 状态表示:dp[i] 表示走到第 i 阶的最小花费
  2. 状态转移方程:dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2])
  3. 初始化:表的长度要比 cost 大 1,表示楼顶
  4. 填表顺序:顺序从左向右填表即可
  5. 返回值:dp[n]

解题代码:

// 时间复杂度:O(N)
// 空间复杂度:O(N)
class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        if (n == 2) return Math.min(cost[0], cost[1]);
        int[] dp = new int[n + 1];
        for (int i = 2; i <= n; i++) {
            dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
        }
        return dp[n];
    }
}

五、91.解码方法

题目:91.解码方法

题目描述:给我们一个编码规则,数字 1 - 26 对应表示字母 A - Z。给我们一个纯数字的字符串,让我们将字符串进行拆分,拆分后的字符串对应的所有子串都可以对应表示成字母。求可以拆分的种数。

题目解析:

解题思路:

  1. 状态表示:dp[i] 表示字符串中 0 到 i 字符的合法拆分结果
  2. 状态转移方程: 2.1. i 位置上字符为 1 到 9 的字符单独解码成功 dp[i] += dp[i - 1] 2.2. i 与 i-1 位置上的字符组合是 10 到 26 的合法编码 dp[i] += dp[i - 2]
  3. 初始化: 3.1. dp[0]:第一个字符不为 0,就 dp[0] = 1,为 0 就返回 0 3.2. dp[1]:该字符不为 0,dp[1] += dp[0],与第 0 个字符组成合法编码 10 - 26,dp[1] += 1

填表顺序:从左到右 返回值:dp[n - 1]

解题代码:

class Solution {
    public int numDecodings(String s) {
        if (s.charAt(0) == '0') return 0;
        int n = s.length();
        char[] ch = s.toCharArray();
        if (n == 1) return 1;
        int[] dp = new int[n];
        dp[0] = 1;
        if (ch[1] != '0' && ch[0] != '0') dp[1] += 1;
        int t = (ch[1] - '0') + (ch[0] - '0') * 10;
        if (t >= 10 && t <= 26) dp[1] += 1;
        for (int i = 2; i < n; i++) {
            if (ch[i] != '0') dp[i] += dp[i - 1];
            t = (ch[i] - '0') + (ch[i - 1] - '0') * 10;
            if (t >= 10 && t <= 26) dp[i] += dp[i - 2];
        }
        return dp[n - 1];
    }
}

目录

  1. 一、动态规划解题模版
  2. 二、第 N 个泰波那契数
  3. 三、面试题 08.01. 三步问题
  4. 四、746. 使用最小花费爬楼梯(easy)
  5. 五、91.解码方法

更多推荐文章

查看全部
  • Android 设计模式:Builder 模式详解与应用
  • 次模函数与机器学习中的离散优化
  • PyTorch 2.0 深度学习入门与实战指南
  • QUEST 一体机本地游戏安装指南:SideQuest 使用详解
  • Spring Cloud Alibaba 集成 SkyWalking 全链路追踪实战
  • Python 自动化采集音乐数据实战:解决反爬与代理配置
  • 前端水印与反爬的实现思路
  • Docker 多容器编排:Compose 实战教程
  • ROS2 TF 系统:机器人坐标系管理详解
  • Python 文本转 PDF 指南:从字符串与 TXT 文件到专业文档
  • LLaMA Factory 核心原理讲解
  • 从零搭建哪吒服务器探针 - 查看多端服务器状态
  • 通义万相 2.1 视频生成模型部署与架构解析
  • Docker部署OnlyOffice社区版,文档保存失败踩坑记录
  • Linux 信号处理:可重入函数原理与实战规范
  • 本地部署 AI 绘画:基于 Flux 模型的快速实践指南
  • 产品经理如何利用 AI 工具提升工作效率与核心竞争力
  • 主流开源 RSS 阅读器精选:桌面与移动端最佳实践
  • Claude/GPT/Codex 中转站选择指南:价格、稳定性与避坑要点
  • Python 帧对象:执行模型与运行期状态解析

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online