每日一题 213. 打家劫舍 II

难度:中等
在这里插入图片描述
思路:

  1. 首先不看成环,只是当作列表,那么对于第 i 间房,到 i 为止的最高偷窃金额为 f(i) = max(f(i - 1), f(i - 2) + nums[i])
  2. 分析递推关系
  3. 第一点,不管 i - 2 处的房子是否偷窃,i 处的房子都能偷窃,即如果无视 i - 1 处的房子的偷窃情况,那么 i 处的房子必定是要偷窃才能使得到 i 为止的偷窃金额最大
  4. 第二点,如果 i - 1 处的房子没有偷窃,i 处的房子才可以偷窃,那么既然 i - 1处的房子没有偷窃,这种情况就和第一点提到的无视 i - 1 处的房子的偷窃情况相符合
  5. 第三点,如果 i - 1 处的房子偷窃了,那么 i 处的房子没得选,只能不偷,也就是保持 f(i - 1) 不变
  6. 总之只要从第一点和第二点中选择较大的那种情况即可,在代码中只需设 a, b = nums[0], max(nums[0], nums[1]),然后不断地更新a,b的值即可
  7. 最后考虑到房子是成环的,所以如果考虑到 nums[0] 偷窃了,那么只需遍历更新到 nums[-2] 即可;如果 nums[0] 禁止偷窃,那么需设 a, b = 0, nums[1],这时需要遍历整个 nums 数组
class Solution:
    def rob(self, nums: List[int]) -> int:
        if len(nums) == 1:
            return nums[0]
        
        a, b = nums[0], max(nums[0], nums[1])
        for i in range(2, len(nums) - 1):
            a, b = b, max(b, a + nums[i])

        if b >= a + nums[-1]:
            return b
        ans = max(a, b)

        a, b = 0, nums[1]
        for i in range(2, len(nums)):
            a, b = b, max(b, a + nums[i])

        return max(a, b, ans)

学习:对于 for 循环的重复部分可以写成函数的形式来调用以简化代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

eyvr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值