第 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)。