difficulty:簡單
你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。
給定乙個代表每個房屋存放金額的非負整數陣列,計算你不觸動警報裝置的情況下,一夜之內能夠偷竊到的最高金額。
示例 1:
輸入:[1,2,3,1]
輸出:4
解釋:偷竊 1 號房屋 (金額 = 1) ,然後偷竊 3 號房屋 (金額 = 3)。
偷竊到的最高金額 = 1 + 3 = 4 。
示例 2:
輸入:[2,7,9,3,1]
輸出:12
解釋:偷竊 1 號房屋 (金額 = 2), 偷竊 3 號房屋 (金額 = 9),接著偷竊 5 號房屋 (金額 = 1)。
偷竊到的最高金額 = 2 + 9 + 1 = 12 。
solution
這是一道考察動態規劃的題目,關鍵的地方在於想出遞推的公式,假設有k間房子,設小偷在第i間房子的收益為f(k),那麼此時小偷有兩種選擇:偷或者不偷,如果偷的話此時的f(k)=f(k-2)+nums[i]
,如果選擇不偷那麼f(k) = f(k-1)
。所以,小偷的最大收益為max(f(k-2)+nums[i],f(k-1))
解法一:容易理解,但是因為nums的節點被使用了多次,最終的提交超出了時間限制,沒有通過。
class solution:
def rob(self, nums: list[int]) -> int:
return self.robhelper(nums, len(nums)-1)
def robhelper(self, nums, i):
if i < 0: return 0
return max(self.robhelper(nums, i-2) + nums[i], self.robhelper(nums, i-1))
解法二:
初始化乙個dp陣列,dp[i]表示偷第i個房間的獲得的金額,時間複雜度和空間複雜度都是o(n)
。計算dp陣列的時候需要保證計算dp[i]
的時候,i之前的dp都已經計算出來了。dp[0]
和dp[1]
可以提前得出。
class solution:
def rob(self, nums: list[int]) -> int:
if not nums: return 0
# 初始化dp陣列
dp = [0] * (len(nums) + 1)
dp[0], dp[1] = 0, nums[0]
for i in range(2, len(nums) + 1):
dp[i] = max(dp[i-2] + nums[i-1], dp[i-1])
return dp[len(nums)]
LeetCode 198 打家劫舍
題目 你是乙個專業的強盜,計畫搶劫沿街的房屋。每間房都藏有一定的現金,阻止你搶劫他們的唯一的制約因素就是相鄰的房屋有保安系統連線,如果兩間相鄰的房屋在同一晚上被闖入,它會自動聯絡 給定乙個代表每個房屋的金額的非負整數列表,確定你可以在沒有提醒 的情況下搶劫的最高金額。思路 本題的大致意思就是求取乙個...
LeetCode198 打家劫舍
你是乙個專業的強盜,計畫搶劫沿街的房屋。每間房都藏有一定的現金,阻止你搶劫他們的唯一的制約因素就是相鄰的房屋有保安系統連線,如果兩間相鄰的房屋在同一晚上被闖入,它會自動聯絡 給定乙個代表每個房屋的金額的非負整數列表,確定你可以在沒有提醒 的情況下搶劫的最高金額。簡單的動態規劃問題,題目意思是計算陣列...
LeetCode198 打家劫舍
你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。給定乙個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。示例 1 輸入 1...