代码随想录算法训练营第四十天|(打家劫舍)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)
        
相关推荐
minji...21 分钟前
Linux 进程信号(二)信号的保存,sigset_t,sigprocmask,sigpending
linux·运维·服务器·网络·数据结构·c++·算法
罗湖老棍子38 分钟前
最大数(信息学奥赛一本通- P1549)(洛谷-P1198)
数据结构·算法·线段树·单点修改 区间求最大值
小O的算法实验室2 小时前
2026年KBS,赏金猎人优化算法+多无人机移动边缘计算与路径规划,深度解析+性能实测
算法·无人机·边缘计算
用户5671504710212 小时前
OpenClaw 记忆管理系统技术文档
算法
935962 小时前
练习题53-60
算法·深度优先
霖大侠3 小时前
Wavelet Meets Adam: Compressing Gradients forMemory-Efficient Training
人工智能·深度学习·算法·机器学习·transformer
AI成长日志3 小时前
【笔面试算法学习专栏】二分查找专题:力扣hot100经典题目深度解析
学习·算法·面试
lcreek3 小时前
流量优化之道:Ford-Fulkerson 最大流算法
算法·
垫脚摸太阳3 小时前
第 36 场 蓝桥·算法挑战赛·百校联赛---赛后复盘
数据结构·c++·算法
Aaswk3 小时前
刷题笔记(回溯算法)
数据结构·c++·笔记·算法·leetcode·深度优先·剪枝