selected_coding_interview/docs/198. 打家劫舍.md
典型的动态规划,以下按照标准流程解题。
状态定义:
转移方程:
设: 有 $n$ 个房子,前 $n$ 间能偷窃到的最高金额是 $dp[n]$ ,前 $n-1$ 间能偷窃到的最高金额是 $dp[n-1]$ ,此时向这些房子后加一间房,此房间价值为 $num$ ;
加一间房间后: 由于不能抢相邻的房子,意味着抢第 $n+1$ 间就不能抢第 $n$ 间;那么前 $n+1$ 间房能偷取到的最高金额 $dp[n+1]$ 一定是以下两种情况的 较大值 :
细心的我们发现: 难道在前 $n$ 间的最高金额 $dp[n]$ 情况下,第 $n$ 间一定被偷了吗?假设没有被偷,那 $n+1$ 间的最大值应该也可能是 $dp[n+1] = dp[n] + num$ 吧?其实这种假设的情况可以被省略,这是因为:
最终的转移方程: $dp[n+1] = max(dp[n],dp[n-1]+num)$
初始状态:
返回值:
简化空间复杂度:
cur和 pre 交替记录,将空间复杂度降到 $O(1)$ 。nums 需要线性时间;cur和 pre 使用常数大小的额外空间。<,,,,,,>
class Solution:
def rob(self, nums: List[int]) -> int:
cur, pre = 0, 0
for num in nums:
cur, pre = max(pre + num, cur), cur
return cur
class Solution {
public int rob(int[] nums) {
int pre = 0, cur = 0, tmp;
for(int num : nums) {
tmp = cur;
cur = Math.max(pre + num, cur);
pre = tmp;
}
return cur;
}
}