代码随想录算法训练营第四十天|(打家劫舍)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)
        
相关推荐
CoovallyAIHub4 小时前
港大&字节重磅发布DanceGRPO:突破视觉生成RLHF瓶颈,多项任务性能提升超180%!
深度学习·算法·计算机视觉
CoovallyAIHub5 小时前
英伟达ViPE重磅发布!解决3D感知难题,SLAM+深度学习完美融合(附带数据集下载地址)
深度学习·算法·计算机视觉
聚客AI1 天前
🙋‍♀️Transformer训练与推理全流程:从输入处理到输出生成
人工智能·算法·llm
大怪v1 天前
前端:人工智能?我也会啊!来个花活,😎😎😎“自动驾驶”整起!
前端·javascript·算法
惯导马工1 天前
【论文导读】ORB-SLAM3:An Accurate Open-Source Library for Visual, Visual-Inertial and
深度学习·算法
骑自行车的码农1 天前
【React用到的一些算法】游标和栈
算法·react.js
博笙困了1 天前
AcWing学习——双指针算法
c++·算法
moonlifesudo1 天前
322:零钱兑换(三种方法)
算法
NAGNIP2 天前
大模型框架性能优化策略:延迟、吞吐量与成本权衡
算法
美团技术团队2 天前
LongCat-Flash:如何使用 SGLang 部署美团 Agentic 模型
人工智能·算法