問題描述
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)