代码随想录算法训练营第四十天|(打家劫舍)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)
        
相关推荐
沐怡旸1 小时前
【算法--链表】114.二叉树展开为链表--通俗讲解
算法·面试
一只懒洋洋1 小时前
K-meas 聚类、KNN算法、决策树、随机森林
算法·决策树·聚类
方案开发PCBA抄板芯片解密2 小时前
什么是算法:高效解决问题的逻辑框架
算法
songx_993 小时前
leetcode9(跳跃游戏)
数据结构·算法·游戏
小白狮ww3 小时前
RStudio 教程:以抑郁量表测评数据分析为例
人工智能·算法·机器学习
AAA修煤气灶刘哥3 小时前
接口又被冲崩了?Sentinel 这 4 种限流算法,帮你守住后端『流量安全阀』
后端·算法·spring cloud
kk”4 小时前
C语言快速排序
数据结构·算法·排序算法
纪元A梦4 小时前
贪心算法应用:基因编辑靶点选择问题详解
算法·贪心算法
3壹4 小时前
数据结构精讲:栈与队列实战指南
c语言·开发语言·数据结构·c++·算法
skytier5 小时前
Construct内报错和定位解决
算法