面试考官考了leetcode打家劫舍系列的1/2,索性把这类题整理一下。
ps:动归果然是常考点
lc198 打家劫舍
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
分析:
- 确定dp数组:目标是小偷要偷到最多的钱,因此dp[i]表示小偷偷前i个房子的最高金额。
- 递推方程式:题目约束是小偷不能偷相邻两间房子,因此当小偷处于第i间房子决策他是否要偷第i间房子的钱时,要考虑他是否偷了第i-1间房子的钱。那么计算dp[i]时,有两种情况(1)小偷偷了第i-1间房的钱,不能偷第i间房的钱(2)小偷没偷第i-1间房的钱,可以偷第i间房的钱。二者取最大。
dp[i] = max(dp[i-2]+nums[i], dp[i-1]) - dp初始化:i=0时,小偷无房可偷dp[0] = 0; i=1时,小偷偷第一间房dp[1] = nums[0];i=2时,因为不能偷连续两间房,dp[2]=max(nums[0],nums[1])
- 遍历方式:顺序遍历
class Solution:
def rob(self, nums: List[int]) -> int:
n = len(nums)
if n == 0:
return 0
dp = [0] * (n+1)
for i in range(1,n+1):
if i == 1:
dp[i] = nums[0]
elif i == 2:
dp[i] = max(nums[0]