二刷 LeetCode:118. 杨辉三角 & 198. 打家劫舍 复盘笔记

目录

[一、118. 杨辉三角](#一、118. 杨辉三角)

题目回顾

思路复盘

代码实现(Java)

[易错点 & 二刷心得](#易错点 & 二刷心得)

[二、198. 打家劫舍](#二、198. 打家劫舍)

题目回顾

思路复盘

[基础 DP 实现(Java)](#基础 DP 实现(Java))

[空间优化版(O (1) 空间)](#空间优化版(O (1) 空间))

[易错点 & 二刷心得](#易错点 & 二刷心得)

[三、两道题的共性总结 & 二刷收获](#三、两道题的共性总结 & 二刷收获)


这两道题分别是动态规划入门经典一维 DP的代表,也是面试高频考点。二刷时我们重点拆解思路、优化写法,顺便把易错点和通用模板总结清楚。


一、118. 杨辉三角

题目回顾

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

思路复盘

杨辉三角的核心规律:

  1. i 行(从 0 开始)有 i+1 个元素
  2. 每行的第一个和最后一个元素都是 1
  3. 中间元素:triangle[i][j] = triangle[i-1][j-1] + triangle[i-1][j]
代码实现(Java)

java

运行

复制代码
public List<List<Integer>> generate(int numRows) {
    List<List<Integer>> result = new ArrayList<>();
    for (int i = 0; i < numRows; i++) {
        List<Integer> row = new ArrayList<>();
        // 每行首尾为1
        for (int j = 0; j <= i; j++) {
            if (j == 0 || j == i) {
                row.add(1);
            } else {
                // 中间元素 = 上一行的两个元素之和
                row.add(result.get(i-1).get(j-1) + result.get(i-1).get(j));
            }
        }
        result.add(row);
    }
    return result;
}

易错点 & 二刷心得

  1. 索引处理 :注意行号从 0 开始,第 i 行的长度是 i+1,避免越界。
  2. 边界元素 :每行首尾元素必须单独处理为 1,否则会出现 i-1j-1 为负的越界错误。
  3. 空间优化 :如果题目只要求返回第 k 行,可以用一维数组滚动更新,空间复杂度从 O (n²) 降到 O (n)。

二、198. 打家劫舍

题目回顾

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

思路复盘

这是一维动态规划的经典题,核心是定义状态和状态转移方程。

  1. 状态定义dp[i] 表示前 i 间房屋能偷窃到的最高金额。
  2. 状态转移
    • 对于第 i 间房屋,有两种选择:
      1. 偷第 i 间:那么不能偷第 i-1 间,最高金额为 dp[i-2] + nums[i]
      2. 不偷第 i 间:最高金额为 dp[i-1]
    • 状态转移方程:dp[i] = max(dp[i-1], dp[i-2] + nums[i])
  3. 初始状态
    • dp[0] = nums[0](只有一间房,偷它)
    • dp[1] = max(nums[0], nums[1])(两间房,偷金额大的)
  4. 结果dp[n-1](n 为房屋数量)
基础 DP 实现(Java)

java

运行

复制代码
public int rob(int[] nums) {
    if (nums == null || nums.length == 0) return 0;
    if (nums.length == 1) return nums[0];
    int n = nums.length;
    int[] dp = new int[n];
    dp[0] = nums[0];
    dp[1] = Math.max(nums[0], nums[1]);
    for (int i = 2; i < n; i++) {
        dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i]);
    }
    return dp[n-1];
}
空间优化版(O (1) 空间)

因为 dp[i] 只依赖 dp[i-1]dp[i-2],所以可以用两个变量滚动更新,空间复杂度从 O (n) 降到 O (1):

java

运行

复制代码
public int rob(int[] nums) {
    if (nums == null || nums.length == 0) return 0;
    if (nums.length == 1) return nums[0];
    int prevPrev = nums[0];
    int prev = Math.max(nums[0], nums[1]);
    for (int i = 2; i < nums.length; i++) {
        int current = Math.max(prev, prevPrev + nums[i]);
        prevPrev = prev;
        prev = current;
    }
    return prev;
}

易错点 & 二刷心得

  1. 边界处理:数组长度为 0 或 1 时要单独判断,避免索引越界。
  2. 状态转移的理解dp[i] 表示前 i 间的最高金额,不是偷第 i 间的最高金额,所以不偷第 i 间时,dp[i] = dp[i-1]
  3. 空间优化技巧:一维 DP 中,如果当前状态只依赖前两个状态,就可以用变量代替数组,大幅降低空间复杂度。

三、两道题的共性总结 & 二刷收获

  1. 动态规划的入门模板
    • 杨辉三角:二维 DP 的基础,从简单的递推关系入手,理解 "上一行推导下一行" 的思路。
    • 打家劫舍:一维 DP 的经典,学会定义状态、找到转移方程,理解 "选 / 不选" 两种决策的逻辑。
  2. 优化意识
    • 从二维数组到一维数组,再到变量滚动更新,体会空间优化的思路。
    • 二刷时不仅要写出正确的代码,还要思考如何优化时间和空间复杂度。
  3. 面试重点
    • 杨辉三角:重点是边界处理和递推关系,常作为 DP 入门题考察。
    • 打家劫舍:重点是状态转移方程和空间优化,后续的环形打家劫舍、打家劫舍 III 都是它的变形题。
相关推荐
江畔柳前堤8 小时前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Forever Nore10 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考11 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
GlueNa2SiO312 小时前
第十八章 Linux故障排查与恢复
linux·服务器·笔记·学习
蛋先生DX12 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面12 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号13 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
xian_wwq13 小时前
【学习笔记】Context Engineering,AI Agent 真正的内存管理-4/16
笔记·学习·context
月光船幽幽13 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI13 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研