你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。
給定乙個代表每個房屋存放金額的非負整數陣列,計算你不觸動警報裝置的情況下 ,一夜之內能夠偷竊到的最高金額。
示例 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 。
思考:
考慮是否偷第i家,如果偷的話則f(i
)=ai
+f(i
−2
)f(i)=a_+f(i-2)
f(i)=a
i+f
(i−2
),如果不偷的話f(i
)=f(
i−1)
f(i)=f(i-1)
f(i)=f
(i−1
)。那麼什麼時候偷什麼時候不偷呢?
考慮最終金額f(i
)f(i)
f(i)
。如果ai+
f(i−
2)
>f(
i−1)
a_+f(i-2)>f(i-1)
ai+f(
i−2)
>f(
i−1)
偷,反之則不偷。
其中f (1
)=a1
,f(2
)=ma
x(a1
,a2)
f(1)=a_,f(2)=max(a_, a_)
f(1)=a
1,f
(2)=
max(
a1,
a2)
class
solution
int size = nums.
size()
;if(size ==1)
vector<
int> dp = vector<
int>
(size,0)
; dp[0]
= nums[0]
; dp[1]
=max
(nums[0]
, nums[1]
);for(
int i =
2; i < size; i++
)return dp[size -1]
;}};
上述方法使用了陣列儲存結果。考慮到每間房屋的最高總金額只和該房屋的前兩間房屋的最高總金額相關,因此可以使用滾動陣列,在每個時刻只需要儲存前兩間房屋的最高總金額。
class
solution
int size = nums.
size()
;if(size ==1)
int first = nums[0]
, second =
max(nums[0]
, nums[1]
);for(
int i =
2; i < size; i++
)return second;}}
;
複雜度分析
時間複雜度:o(n),其中 n是陣列長度。只需要對陣列遍歷一次。
空間複雜度o(1)。使用滾動陣列,可以只儲存前兩間房屋的最高總金額,而不需要儲存整個陣列的結果,因此空間複雜度是 o(1)。
LeetCode 打家劫舍(198)
你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。給定乙個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。示例 1 輸入 1...
198House Robber打家劫舍
你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。給定乙個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。示例 1 輸入 1...
打家劫舍 LeetCode 198
這是一道線性動態規劃,當前的狀態只與特定數量的前邊狀態相關。狀態的定義 dp i 小偷偷到第i間房時,偷到的最大金額為dp i 狀態轉移方程 dp i max dp i 1 dp i 2 nums i 初始狀態 dp 0 0 dp 1 nums 0 直接使用dp陣列的,沒有進行空間優化 class ...