首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

LeetCode 198:打家劫舍問題完整解析與動態規劃實現

     編輯:關於C++

問題描述

你是一名專業強盜,計劃沿著一條街道依次打劫房屋。每間房屋內存放著一定數量的現金,但相鄰房屋之間裝有防盜系統,若同一夜連續闖入兩間相鄰房屋,系統會自動報警。給定一個非負整數陣列,代表每間房屋的金額,請計算在不觸發警報的前提下,一夜之間能竊取的最大金額。

核心思路:動態規劃

這是一個經典的動態規劃問題。對於第 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 間房屋所能獲得的最大金額。

C++ 參考實現

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;
}

複雜度分析

  • 時間複雜度:O(n),單次遍歷陣列。
  • 空間複雜度:O(1)(優化版)或 O(n)(陣列版)。

測試範例

範例示意圖

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

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved