从斐波那契到动态规划:两道入门题吃透 DP 核心思想

目录

前言

一、爬楼梯:从斐波那契到动态规划

题目描述

[1. 核心思路:拆解问题](#1. 核心思路:拆解问题)

[2. 代码实现(Java 版)](#2. 代码实现(Java 版))

[3. 关键知识点](#3. 关键知识点)

[二、杨辉三角:二维 DP 的入门实践](#二、杨辉三角:二维 DP 的入门实践)

题目描述

[1. 核心思路:二维状态转移](#1. 核心思路:二维状态转移)

[2. 代码实现(Java 版)](#2. 代码实现(Java 版))

[3. 关键知识点](#3. 关键知识点)


前言

动态规划(DP)是算法面试的高频考点,很多同学刚接触时,总觉得它 "又抽象又难理解"。其实入门阶段,两道经典题就能帮你捅破这层窗户纸:一道是《爬楼梯》,一道是《杨辉三角》。

今天我们就从这两道题入手,从问题拆解、状态定义、转移方程一步步讲透,帮你建立 DP 的基本思维框架。


一、爬楼梯:从斐波那契到动态规划

题目描述

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 12 个台阶。你有多少种不同的方法可以爬到楼顶呢?

1. 核心思路:拆解问题

我们先从一个简单的例子入手:

  • 爬到第 1 阶:只有 1 种方法(直接爬 1 阶)
  • 爬到第 2 阶:有 2 种方法(1+1 / 2)
  • 爬到第 3 阶:最后一步要么从第 2 阶爬 1 阶上来,要么从第 1 阶爬 2 阶上来 → 方法数 = f(2) + f(1)
  • 爬到第 n 阶:同理,方法数 = f(n-1) + f(n-2)

这就是典型的动态规划递推关系

  • 状态定义dp[i] 表示爬到第 i 阶的方法数
  • 转移方程dp[i] = dp[i-1] + dp[i-2]
  • 初始条件dp[1] = 1dp[2] = 2

2. 代码实现(Java 版)

java

运行

复制代码
public class ClimbStairs {
    // 动态规划基础版(数组存储)
    public int climbStairs(int n) {
        if (n <= 2) return n;
        int[] dp = new int[n + 1];
        dp[1] = 1;
        dp[2] = 2;
        for (int i = 3; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }

    // 优化版(滚动变量,空间O(1))
    public int climbStairsOptimized(int n) {
        if (n <= 2) return n;
        int a = 1, b = 2;
        for (int i = 3; i <= n; i++) {
            int temp = a + b;
            a = b;
            b = temp;
        }
        return b;
    }

    public static void main(String[] args) {
        ClimbStairs solution = new ClimbStairs();
        System.out.println(solution.climbStairs(5)); // 输出:8
        System.out.println(solution.climbStairsOptimized(5)); // 输出:8
    }
}

3. 关键知识点

  • 这道题本质就是斐波那契数列,但用 DP 的思路更直观。
  • 时间复杂度:O (n),空间复杂度可以优化到 O (1)(只保留前两个状态)。
  • 面试拓展:如果每次可以爬 k 阶,转移方程就变成 dp[i] = sum(dp[i-k] ... dp[i-1]),核心思想不变。

二、杨辉三角:二维 DP 的入门实践

题目描述

给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。在「杨辉三角」中,每个数是它左上方和右上方的数的和。

1. 核心思路:二维状态转移

杨辉三角的核心规律:

  • i 行有 i 个元素(从第 0 行开始计数)
  • 每行的首尾元素都是 1
  • 中间元素 triangle[i][j] = triangle[i-1][j-1] + triangle[i-1][j]

这是典型的二维动态规划

  • 状态定义triangle[i][j] 表示第 i 行第 j 列的元素值
  • 转移方程triangle[i][j] = triangle[i-1][j-1] + triangle[i-1][j](首尾元素除外)
  • 初始条件 :每行首尾元素为 1

2. 代码实现(Java 版)

java

运行

复制代码
import java.util.ArrayList;
import java.util.List;

public class PascalTriangle {
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> triangle = new ArrayList<>();
        if (numRows == 0) return triangle;

        // 第0行
        List<Integer> firstRow = new ArrayList<>();
        firstRow.add(1);
        triangle.add(firstRow);

        // 从第1行开始生成
        for (int i = 1; i < numRows; i++) {
            List<Integer> prevRow = triangle.get(i - 1);
            List<Integer> currRow = new ArrayList<>();
            // 首尾元素为1
            currRow.add(1);
            // 中间元素由上一行计算而来
            for (int j = 1; j < i; j++) {
                currRow.add(prevRow.get(j - 1) + prevRow.get(j));
            }
            currRow.add(1);
            triangle.add(currRow);
        }
        return triangle;
    }

    public static void main(String[] args) {
        PascalTriangle solution = new PascalTriangle();
        List<List<Integer>> result = solution.generate(5);
        for (List<Integer> row : result) {
            System.out.println(row);
        }
        /* 输出:
        [1]
        [1, 1]
        [1, 2, 1]
        [1, 3, 3, 1]
        [1, 4, 6, 4, 1]
        */
    }
}

3. 关键知识点

  • 时间复杂度:O (n²),每个元素只计算一次。
  • 空间复杂度:O (n²),存储整个三角结构;如果只需要第 n 行,可以优化到 O (n)。
  • 面试拓展:杨辉三角的变种题,如求第 n 行的元素和、求第 n 行第 k 列的元素,都可以用同样的 DP 思路解决。
相关推荐
米啦啦.2 小时前
多态性、虚函数
开发语言·c++·算法·多态·抽象类·纯虚函数
承渊政道2 小时前
【递归、搜索与回溯算法】(二叉树深搜模型拆解与经典题型全面突破)
数据结构·c++·学习·算法·leetcode·macos·bfs
会编程的土豆2 小时前
常用算法里的细节
数据结构·c++·算法·图论
skilllite作者2 小时前
为什么我认为 Hermes 需要说明 self-evolution 的设计来源
人工智能·算法·rust·openclaw·agentskills
tankeven2 小时前
HJ179 小苯的IDE括号问题(easy)
c++·算法
华农DrLai2 小时前
什么是推荐系统中的负反馈?用户的“踩“和“不感兴趣“怎么用?
人工智能·算法·llm·prompt·知识图谱
木斯佳2 小时前
前端八股文面经大全:京东零售JDY前端一面(2026-04-14)·面经深度解析
前端·算法·设计模式·ai·断点续传
zore_c2 小时前
【C++】C++——类的默认成员函数(构造、析构、拷贝构造函数)
java·c语言·c++·笔记·算法·排序算法
生信研究猿2 小时前
第2题-模型推理量化加速优化问题
python·算法