day34-数据结构力扣

198.打家劫舍

题目链接 198. 打家劫舍 - 力扣(LeetCode)

思路

1. 确定 dp 数组含义

dpi:下标为 i 以内的房屋,能偷窃到的最大金额。

2. 递推公式

不能偷相邻房屋:

  • 偷第 i 间:就不能偷 i−1,金额 = dpi−2+numsi

  • 不偷第 i 间:金额 = dpi−1

  • dpi=max(dpi−1, dpi−2+numsi)

3. 初始化

  • dp0=nums0 只一间房,必偷

  • dp1=max(nums0,nums1) 两间房选钱多的

4. 遍历顺序

从左到右,i 从 2 遍历到末尾。

提交

python 复制代码
class Solution:
    def rob(self, nums: List[int]) -> int:
        # 边界情况:没有房屋
        if len(nums) == 0:
            return 0
        # 边界情况:只有一间房屋,直接取该金额
        if len(nums) == 1:
            return nums[0]
        
        n = len(nums)
        # dp[i] 表示前i间房屋能偷窃到的最大金额
        dp = [0] * n
        # 第一间房,只能偷自己
        dp[0] = nums[0]
        # 前两间房,选金额更大的一间
        dp[1] = max(nums[0], nums[1])
        
        # 从第三间房开始遍历推导
        for i in range(2, n):
            # 两种选择:
            # 1.不偷当前房:最大值 = dp[i-1]
            # 2.偷当前房:不能偷上一间,最大值 = dp[i-2] + nums[i]
            dp[i] = max(dp[i-1], dp[i-2] + nums[i])
        # 返回全部房屋的最大偷窃金额
        return dp[-1]

213.打家劫舍II

题目链接213. 打家劫舍 II - 力扣(LeetCode)

思路

核心区别:房屋围成一圈,第一间和最后一间不能同时偷。

因为首尾相连,所以分两种情况取最大:

  1. 不偷最后一间 :只考虑 nums[0] ~ nums[-2]

  2. 不偷第一间 :只考虑 nums[1] ~ nums[-1]

最终答案 = 两种情况的最大值

动规 5 步曲(沿用原版)

  1. dpi:前 i 间房能偷的最大金额

  2. 递推公式 :dp[i] = max(dp[i-1], dp[i-2] + nums[i])

  3. 初始化 :dp[0]=nums[0],dp[1]=max(nums[0],nums[1])

  4. 遍历:从左到右

  5. 结果:数组最后一位

提交

python 复制代码
class Solution:
    def rob(self, nums: List[int]) -> int:
        # 边界:只有一间房,直接返回
        if len(nums) == 1:
            return nums[0]
        
        # 核心:环形 = 两个线性问题取最大
        # 情况1:不偷最后一间 → 范围 [0, len-2]
        # 情况2:不偷第一间 → 范围 [1, len-1]
        return max(
            self.rob_range(nums, 0, len(nums)-2),
            self.rob_range(nums, 1, len(nums)-1)
        )

    # 原版打家劫舍:计算 [start, end] 区间的最大金额
    def rob_range(self, nums: List[int], start: int, end: int) -> int:
        # 区间只有一间房
        if start == end:
            return nums[start]
        
        # 初始化dp
        dp = [0] * len(nums)
        dp[start] = nums[start]
        dp[start+1] = max(nums[start], nums[start+1])
        
        # 从第三间开始递推
        for i in range(start+2, end+1):
            # 不偷当前 = dp[i-1]
            # 偷当前 = dp[i-2] + 当前金额
            dp[i] = max(dp[i-1], dp[i-2] + nums[i])
        
        return dp[end]

337.打家劫舍III

题目链接 337. 打家劫舍 III - 力扣(LeetCode)

怎么把二叉树搞进来了

思路

题目核心

房屋组成二叉树 ,父子节点不能同时偷,求最大金额。树形 DP,后序遍历,每个节点返回两个状态:

  1. 选当前节点的最大金额
  2. 不选当前节点的最大金额

动规五步曲

1.dp 含义

对每个节点,返回长度为 2 的数组:

  • res[0]:不偷当前节点,子树最大金额

  • res[1]:偷当前节点,子树最大金额

2.递推公式

  • 偷当前节点:左右孩子都不能偷res1=root.val+left0+right0

  • 不偷当前节点:左右孩子可选偷 / 不偷,取最大值res0=max(left0,left1)+max(right0,right1)

3.初始化

空节点return0,0

4.遍历顺序

二叉树后序遍历:先左、再右、最后根

5.结果推导

最终答案:max(根节点【0】,根节点【0】)

提交

python 复制代码
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def rob(self, root: Optional[TreeNode]) -> int:
        # 返回 [不偷当前节点最大值, 偷当前节点最大值]
        def dfs(node):
            # 空节点,左右都无收益
            if not node:
                return [0, 0]
            
            left = dfs(node.left)   # 左子树状态
            right = dfs(node.right) # 右子树状态
            
            # 1. 偷当前节点:左右孩子一定不能偷
            rob_cur = node.val + left[0] + right[0]
            # 2. 不偷当前节点:左右孩子随便选,取最大
            not_rob_cur = max(left[0], left[1]) + max(right[0], right[1])
            
            return [not_rob_cur, rob_cur]
        
        root_res = dfs(root)
        # 根节点偷或不偷,取最大值
        return max(root_res[0], root_res[1])
相关推荐
扶风ff6 分钟前
练题簿在线免费刷题:会员线下组卷、Word 试卷与成绩导入,课堂检测更方便
java·开发语言·算法·小程序·word
yi01113 分钟前
LeetCode 15:三数之和|排序 + 双指针,如何避免重复答案?
笔记·python·算法·leetcode·双指针
-dzk-29 分钟前
【多维动态规划】LC 1143.最长公共子序列
算法·动态规划
C++ 老炮儿的技术栈34 分钟前
char (*csConnectName)[256]; 和 char csConnectName [256] 有什么区别
java·c语言·开发语言·c++·人工智能·算法·c
Omics Pro44 分钟前
全新可重分析!代谢组质谱专用
数据库·人工智能·算法·机器学习·自然语言处理
Nebula_g44 分钟前
JavaSE加强:线程Thread(线程安全重点)
java·开发语言·jvm·算法·javase·技术栈
一只废狗狗狗狗狗狗狗狗狗1 小时前
Network架构1——卷积神经网络CNN
人工智能·算法·cnn
是希燃亚1 小时前
AI Agent 的未来,可能不是更强,而是更简单
算法·架构
alphaTao1 小时前
LeetCode 每日一题 2026/10/5-2026/10/11
算法·leetcode
liliangcsdn1 小时前
现金流指标的探索和分析
大数据·算法