34

打家劫舍

·2 分钟

🟡 Medium · 🏷️ 动态规划 · LeetCode#198

📖 题目

沿街的房屋里各藏着一笔钱,相邻的两间不能同时偷,求能偷到的最高金额。

输入输出说明
nums=[2,7,9,3,1]12偷 2+9+1(跳过相邻的)

💡 思路

爬楼梯是同一个"只看前两个状态"的DP骨架,区别是爬楼梯求的是方案数(加法),这题求的是最大收益(取最大值)。

站在第 i 家,只有两种选择:它(拿到 nums[i],但第 i-1 家就不能抢了,所以是 nums[i] + dp[i-2]),或者不抢它(收益就是 dp[i-1])。两者取较大的:

dp[i] = max(nums[i] + dp[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:
        n = len(nums)
        if n == 1:
            return nums[0]
        a, b = nums[0], max(nums[0], nums[1])
        for i in range(2, n):
            a, b = b, max(nums[i] + a, b)
        return b

只依赖前两个状态,跟爬楼梯一样用滚动变量代替数组。时间复杂度 O(n),空间复杂度 O(1)。