你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。給定乙個代表每個房屋存放金額的非負整數陣列,計算你不觸動警報裝置的情況下 ,一夜之內能夠偷竊到的最高金額。
示例 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 。
首先考慮最簡單的情況。如果只有一間房屋,則偷竊該房屋,可以偷竊到最高總金額。如果只有兩間房屋,則由於兩間房屋相鄰,不能同時偷竊,只能偷竊其中的一間房屋,因此選擇其中金額較高的房屋進行偷竊,可以偷竊到最高總金額。
如果房屋數量大於兩間,應該如何計算能夠偷竊到的最高總金額呢?對於第 k(k>2)間房屋,有兩個選項:
在兩個選項中選擇偷竊總金額較大的選項,該選項對應的偷竊總金額即為前 k 間房屋能偷竊到的最高總金額。
用 dp[i] 表示前 i 間房屋能偷竊到的最高總金額,那麼就有如下的狀態轉移方程:
dp[i]=max(dp[i−2]+nums[i],dp[i−1])
邊界條件為:
dp[0]=nums[0]只有一間房屋,則偷竊該房屋
dp[1]=max(nums[0],nums[1])只有兩間房屋,選擇其中金額較高的房屋進行偷竊
最終的答案即為 dp[n−1],其中 n 是陣列的長度。
var
rob=
function
(nums)
return dp[n-1]
;};
複雜度分析
方法二:動態規劃+滾動陣列
對方法一的空間優化。
考慮到每間房屋的最高總金額只和該房屋的前兩間房屋的最高總金額相關,因此可以使用滾動陣列,在每個時刻只需要儲存前兩間房屋的最高總金額。
/**
* @param nums
* @return
*/var
rob=
function
(nums)
return two;
};
空間複雜度:o(1)。使用滾動陣列,可以只儲存前兩間房屋的最高總金額,而不需要儲存整個陣列的結果,因此空間複雜度是 o(1)。 198 打家劫舍
很明顯是dp問題。用乙個一維陣列表示dp陣列,狀態轉移方程為 resmax index max nums index resmax index 2 resmax index 1 其中resmax儲存,遍歷到該節點時的,最大值。注意,遍歷到該節點,但該節點不一定選。另外該題的初始解要想清楚。即resm...
198 打家劫舍
你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。給定乙個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。示例 1 輸入 1...
198 打家劫舍
你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。給定乙個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。示例 1 輸入 1...