代码随想录算法训练营第42天 | 动态规划7:打家劫舍入门

打家劫舍
https://leetcode.cn/problems/house-robber/description/
代码随想录
https://programmercarl.com/0198.打家劫舍.html
打家劫舍-环形
https://leetcode.cn/problems/house-robber-ii/description/
代码随想录
https://programmercarl.com/0213.打家劫舍II.html#思路
打家劫舍-树形
https://leetcode.cn/problems/house-robber-iii/description/
https://programmercarl.com/0337.打家劫舍III.html#其他语言版本

打家劫舍

理论

  • 特点:相邻房间不能访问;
  • 动态规划模版
    • dp数组:dp[i] dp[i]间房子内 最多可以偷到的金额是多少;
    • 递推公式:第i间 房间偷不偷;
      1. 偷上上一间和本间:dp[i-2]+nums[i]
      2. 偷上一间:dp[i-1]
    • 初始化:dp[0] = nums[0] dp[1] = max(nums[0],nums[1])

题解代码

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

        if len(nums) == 0:
            return 0

        dp = [0]*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]

打家劫舍-环形

题解思路

  • 思考限制
    • 前后不能同时选
      1.选0 不选-1
      2.选-1 不选0
      3.都不选
      情况1.2都包括情况3 所以不考虑情况3 分类讨论情况2即可

题解代码

点击查看代码
class Solution:
    def thef(self,nums):
        if len(nums)==1:
            return nums[0]

        if len(nums) == 0:
            return 0

        dp = [0]*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]

    def rob(self, nums: List[int]) -> int:
        if len(nums)==1:
            return nums[0]
        if len(nums)==0:
            return 0
        rob_1 = self.thef(nums[:-1])
        rob_2 = self.thef(nums[1:])
        return max(rob_1,rob_2)

打家劫舍-树形DP

题解思路

  • dp[0][1]
    dp[0] 不选该root 继承子树和的最大值;
    dp[1] 选该root,不选左右子树的和;
    最终结果为两个值中的max
  • 后序遍历
  • 终止条件:空节点;
点击查看代码
class Solution:
    def trans(self,root):
        if not root:
            return (0,0)

        left = self.trans(root.right)
        right = self.trans(root.left)

        val_0 = max(left)+max(right)

        val_1= root.val + left[0]+right[0]  ##0是没选自己

        return (val_0,val_1)


    def rob(self, root: Optional[TreeNode]) -> int:
        res = max(self.trans(root))
        return res
posted @ 2024-07-25 10:33  哆啦**  阅读(1)  评论(0编辑  收藏  举报