代码随想录算法训练营第四十天|(打家劫舍)198.打家劫舍 、 213.打家劫舍II、337.打家劫舍III

打家劫舍问题的思路:代码随想录

dp[i]:考虑下标i(包括i)以内的房屋,最多可以偷窃的金额为dp[i]

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

初始化:dp[0] 一定是 nums[0],dp[1]就是nums[0]和nums[1]的最大值即:dp[1] = max(nums[0], nums[1])

198. 打家劫舍

python 复制代码
class Solution:
    def rob(self, nums: List[int]) -> int:
        if len(nums) == 0:
            return 0
        if len(nums) == 1:
            return nums[0]

        dp = [0 for _ in range(len(nums))]
        dp[0] = nums[0]
        dp[1] = max(nums[0], nums[1])

        for i in range(2, len(nums)):
            dp[i] = max(dp[i-1], dp[i-2] + nums[i])
        
        return dp[-1]

213. 打家劫舍 II

此题不用dp数组来记录前面的状态,用pre_max和curr_max来记录

python 复制代码
class Solution:
    def robRange(self, nums, start, end):
        if end == start:
            return nums[start]
        
        pre_max = nums[start]
        curr_max = max(nums[start + 1], nums[start])

        for i in range(start + 2, end + 1):
            temp = curr_max
            curr_max = max(pre_max + nums[i], curr_max)
            pre_max = temp
        
        return curr_max

    def rob(self, nums: List[int]) -> int:
        if len(nums) == 0:
            return 0
        if len(nums) == 1:
            return nums[0]
        
        result1 = self.robRange(nums, 0, len(nums)-2)
        result2 = self.robRange(nums, 1, len(nums) - 1 )        
        return max(result1, result2)

337. 打家劫舍 III

方法一:暴力递归(超出时间限制)

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:
        if root is None:
            return 0
        if root.left is None and root.right is None:
            return root.val
        
        #偷父节点
        val1 = root.val
        if root.left:
            val1 += self.rob(root.left.left) + self.rob(root.left.right)
        if root.right:
            val1 += self.rob(root.right.left) + self.rob(root.right.right)

        #不偷父节点
        val2 = self.rob(root.left) + self.rob(root.right)

        return max(val1, val2)

方法二:动态规划

dp数组含义:此题中dp为一维长度为2的数组,dp[0]表示不偷当前节点时的最大值,dp[1]表示偷当前节点时的最大值。由于递归调用每一层都会传递一个新的dp数组,因此长度为2的dp数组已够用。

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 traversal(self, node):
        if node is None:
            return (0, 0)
        
        left = self.traversal(node.left)
        right = self.traversal(node.right)

        # 不偷当前节点, 偷子节点(判断左右子节点偷/不偷最大)
        val_0 = max(left[0], left[1]) + max(right[0], right[1])

        # 偷当前节点, 不偷子节点
        val_1 = node.val + left[0] + right[0]

        return (val_0, val_1)

    def rob(self, root: Optional[TreeNode]) -> int:
         # dp数组(dp table)以及下标的含义:
        # 1. 下标为 0 记录 **不偷该节点** 所得到的的最大金钱
        # 2. 下标为 1 记录 **偷该节点** 所得到的的最大金钱
        dp = self.traversal(root)
        return max(dp)
        
相关推荐
mit6.82416 小时前
bfs|栈
算法
CoderYanger17 小时前
优选算法-栈:67.基本计算器Ⅱ
java·开发语言·算法·leetcode·职场和发展·1024程序员节
jllllyuz17 小时前
Matlab实现基于Matrix Pencil算法实现声源信号角度和时间估计
开发语言·算法·matlab
稚辉君.MCA_P8_Java17 小时前
DeepSeek 插入排序
linux·后端·算法·架构·排序算法
多多*17 小时前
Java复习 操作系统原理 计算机网络相关 2025年11月23日
java·开发语言·网络·算法·spring·microsoft·maven
.YM.Z18 小时前
【数据结构】:排序(一)
数据结构·算法·排序算法
Chat_zhanggong34518 小时前
K4A8G165WC-BITD产品推荐
人工智能·嵌入式硬件·算法
百***480719 小时前
【Golang】slice切片
开发语言·算法·golang
墨染点香19 小时前
LeetCode 刷题【172. 阶乘后的零】
算法·leetcode·职场和发展
做怪小疯子19 小时前
LeetCode 热题 100——链表——反转链表
算法·leetcode·链表