问题描述
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.
Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.
补充说明:
很有趣的一个题目,假设你是一个江洋大盗,现在你在一个独立的街区,有这么一排房子,每个房子里面拥有不同价值的
财富。进入房子去盗取这些财物,需要注意的是相邻的两个房子被盗就会触发警报招来警察。试问,你在不被发现的情况下可以盗取的最大财物价值多少?
方案分析
- 首先明确一点,相邻的两个房子不能被盗窃。
- 盗窃第i个房子的时候,前面的第i-1个房子有两种状态:第i-1个房子已被盗取,第i-1个房子未被盗取。
- 这里需要记录两个值,rob,not_rob:rob记录的是上一个房子被盗窃的后拥有的价值,not_rob记录的是上一个房子没被盗窃拥有的价值。
- 同理,对待第i个房子的时候,这次盗窃可能存在两个结果:盗取第i个房子,不盗取第i个房子。
- 综上所述,该轮第i个房子是否被盗取的状态取决于第i-1个房子的状态。
先评估本轮盗窃第i个房子的时候,那么上一个房子不能被盗,那么本轮操作完成,能获取的价值是not_rob + 当前第i个房子的价值。
如果本轮不盗窃第i个房子的时候,则需要更新not_rob,未盗窃第i-1的价值和盗窃第i-1的价值中较大的那个值(因为此时本轮没盗窃,上面那轮盗窃不盗窃都不会触发警报)。
同理更新rob,表示盗窃第i个房子的价值。 - 通过这个两个值以及前面3、 4描述的限制,就能限定警报的发生。
python实现
class Solution(object):
def rob(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
rob, not_rob = 0, 0
for num in nums:
cur_rob = not_rob + num # 如果盗窃这个房子,那么上一个房子必须没有被盗窃,否则会触发警报。
not_rob = max(not_rob, rob) # 如果这个房子没有被盗窃,那么盗窃的最大值必须是盗窃这个房子之前那些房子盗窃到的最大值。
rob = cur_rob # 如果这个房子被盗,则将这个盗窃后的值计入到rob中。
return max(rob, not_rob)