Leetcode题解---打家劫舍

 

目录

198. 打家劫舍

213. 打家劫舍 II

337. 打家劫舍 III

198. 打家劫舍

动态规划: 

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

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

213. 打家劫舍 II

我们将原数组拆成两部分
1、nums[0],num[1]...num[end-1]
2、nums[1],nums[2]...nums[end]

然后我们分别对这两个数组求最大值,这个求解过程就完全套用了【打家劫舍 I】的逻辑。
我们只需要用同样的逻辑,执行两边代码,最后求两次的最大值即可。

这里我们创建两个dp数组
dp1计算的是nums[1],nums[2]...nums[end]这个数组
dp2计算的是nums[0],nums[1]...nums[end-1]这个数组

dp1是从nums[1]开始的,所以初的前两个值

dp1[0]就等于0
dp1[1]等于nums[1]
同理,dp2是从nums[0]开始的,所以初始化的前两个值

dp2[0]就等于nums[0]
dp2[1]就等于max(nums[0],nums[1])

class Solution(object):
    def rob(self, nums):
        if not nums:
            return 0
        n = len(nums)
        if n<=2:
            return max(nums)
        dp1 = [0 for _ in xrange(n)]
        dp2 = [0 for _ in xrange(n)]
        # 初始化两个dp数组,dp1是计算的是[1,end],dp2计算的是[0,end-1]
        dp1[0] = 0
        dp1[1] = nums[1]
        dp2[0] = nums[0]
        dp2[1] = max(nums[0],nums[1])
        # 按照【打家劫舍 I】的转移方式执行两遍
        for i in xrange(2,n):
            dp1[i] = max(dp1[i-1],dp1[i-2]+nums[i])
        for i in xrange(2,n-1):
            dp2[i] = max(dp2[i-1],dp2[i-2]+nums[i])
        return max(dp1[-1],dp2[-2])

337. 打家劫舍 III

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def rob(self, root: TreeNode) -> int:
        a = self.helper(root)   # a 是一个二维数组, 为root的[偷值, 不偷值]
        return max(a[0], a[1])  # 返回两个值的最大值, 此值为小偷最终获得的总值
    
    # 参数为root节点, helper方法输出一个二维数组:root节点的[偷值, 不偷值]
    def helper(self, root):     # 递归结束条件:root为空, 输出 [0, 0]
        if not root:
            return [0, 0]
        left = self.helper(root.left)   # left是一个二维数组, 为 root 左侧子节点的[偷值, 不偷值]
        right = self.helper(root.right) # right也是一个二维数组, 为root右侧子节点的[偷值, 不偷值]
        robValue = left[1] + right[1] + root.val    # root 的偷值
        skipValue = max(left[0], left[1]) + max(right[0], right[1]) # root 的不偷值
        return [robValue, skipValue]    # 输出小偷可获得的最大金额

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值