题目: 打家劫舍
来源:Leetcode
经典动态规划问题,由于每个房屋存放金额为非负整数,这简化了问题。
首先我们初始化一个dp数组,用以保存抢到第 i 间屋子时的当前最大收益
我们思考一个问题,当我们到达第 i 间屋子时,我们有两个选择:
- 抢劫第 i 间屋子,根据规则,则 第 i - 1号屋子我们是不能抢的,此时我们的收益是 dp[i - 2] + nums[i]
- 不抢劫第 i 间屋子,那么此时我们的收益就等于 dp[i - 1]
则第i间屋子的收益就为 max(1,2),代码如下:
class Solution:
def rob(self, nums: List[int]) -> int:
dp = [0] * (len(nums) + 1)
for i in range(len(nums)):
dp[i] = max(dp[i-1], dp[i-2] + nums[i])
return max(dp)
可以看到,当前位置的收益其实之和 i-1,i-2有关,因此我们可以采用滚动数组的思想,使用first和second保存前两个位置的收益即可,可进一步优化空间复杂度,代码如下:
class Solution:
def rob(self, nums: List[int]) -> int:
first = second = 0
for i in range(len(nums)):
tmp = second
second = max(first + nums[i], second)
first = tmp
return max(first, second)