你是一名專業強盜,計劃沿著一條街道依次打劫房屋。每間房屋內存放著一定數量的現金,但相鄰房屋之間裝有防盜系統,若同一夜連續闖入兩間相鄰房屋,系統會自動報警。給定一個非負整數陣列,代表每間房屋的金額,請計算在不觸發警報的前提下,一夜之間能竊取的最大金額。
這是一個經典的動態規劃問題。對於第 i 間房屋,我們只有兩種選擇:偷 或 不偷。
i-1 間必須不偷,當前累計最大值為 nums[i-1] + dp[i-2]。dp[i-1]。狀態轉移方程:
dp[i] = max(dp[i-1], dp[i-2] + nums[i-1])
其中 dp[i] 表示打劫前 i 間房屋所能獲得的最大金額。
class Solution {
public:
int rob(vector& nums) {
int n = nums.size();
if (n == 0) return 0;
vector dp(n + 1, 0);
dp[1] = nums[0];
for (int i = 2; i <= n; ++i) {
dp[i] = max(dp[i-1], dp[i-2] + nums[i-1]);
}
return dp[n];
}
};
由於 dp[i] 僅依賴前兩個狀態,可用兩個變數滾動更新,將空間複雜度從 O(n) 降為 O(1):
int rob(vector& nums) { int prev = 0, curr = 0; for (int num : nums) { int temp = max(curr, prev + num); prev = curr; curr = temp; } return curr; }

輸入:[1,2,3,1] → 輸出:4(偷第 1、3 間)
輸入:[2,7,9,3,1] → 輸出:12(偷第 1、3、5 間)