目录
[一、70. 爬楼梯](#一、70. 爬楼梯)
[Java 实现(基础版)](#Java 实现(基础版))
[空间优化版(O (1) 空间)](#空间优化版(O (1) 空间))
[二、118. 杨辉三角](#二、118. 杨辉三角)
[Java 实现](#Java 实现)
这两道题是动态规划的入门经典,也是面试中常考的 "基础送分题"。二刷的目的,不只是写出代码,更是吃透背后的递推逻辑与优化空间。
一、70. 爬楼梯
题目回顾
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
核心思路
这是一道典型的斐波那契数列问题,用动态规划来理解会更清晰:
- 状态定义 :
dp[i]表示爬到第i阶楼梯的方法数。 - 状态转移方程 : 要到达第
i阶,你只能从第i-1阶(爬 1 步)或第i-2阶(爬 2 步)上来,因此:dp[i] = dp[i-1] + dp[i-2] - 边界条件 :
dp[1] = 1,dp[2] = 2
Java 实现(基础版)
java
运行
class Solution {
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) 空间)
因为每次计算只需要前两个状态,所以可以不用数组,直接用两个变量迭代更新即可:
java
运行
class Solution {
public int climbStairs(int n) {
if (n <= 2) return n;
int prevPrev = 1; // dp[i-2]
int prev = 2; // dp[i-1]
for (int i = 3; i <= n; i++) {
int current = prev + prevPrev;
prevPrev = prev;
prev = current;
}
return prev;
}
}
二、118. 杨辉三角
题目回顾
给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中,每个数是它左上方和右上方的数的和。
核心思路
杨辉三角的递推关系非常明确:
- 第
i行(从 0 开始计数)有i+1个元素。 - 每行的第一个和最后一个元素都是
1。 - 中间元素
triangle[i][j] = triangle[i-1][j-1] + triangle[i-1][j]
Java 实现
java
运行
class Solution {
public List<List<Integer>> generate(int numRows) {
List<List<Integer>> result = new ArrayList<>();
if (numRows == 0) return result;
// 第0行
List<Integer> firstRow = new ArrayList<>();
firstRow.add(1);
result.add(firstRow);
for (int i = 1; i < numRows; i++) {
List<Integer> prevRow = result.get(i - 1);
List<Integer> currentRow = new ArrayList<>();
// 开头加1
currentRow.add(1);
// 中间元素
for (int j = 1; j < i; j++) {
currentRow.add(prevRow.get(j - 1) + prevRow.get(j));
}
// 结尾加1
currentRow.add(1);
result.add(currentRow);
}
return result;
}
}
三、二刷感悟
这两道题都是动态规划的 "敲门砖":
- 爬楼梯 让我们理解了一维线性递推和空间优化的核心思想;
- 杨辉三角 则是二维动态规划的入门,帮我们建立 "利用上一行数据计算当前行" 的思维模式。