打家劫舍

GitHub跳转原题关系图返回列表

dp[i] 表示处理到第 i 间时的最大金额,偷当前则跳过前一间,不偷则继承前一间。

OJ: leetcodecn

题目 ID: house-robber

难度:普及-

标签:动态规划递推

日期: 2026-07-29 12:36

题意

不能偷相邻房屋,求最大金额。

思路

ab 分别表示"不偷当前"和"偷当前"的最大金额。a = b(上一轮的偷),b = max(b, a + nums[i])(取偷与不偷的较大值)。空间优化到 O(1)O(1)

代码

cpp
#include <bits/stdc++.h>
using namespace std;

class Solution {
public:
    int rob(vector<int> &nums) {
        int prevTwo = 0, prevOne = 0;
        for (int value : nums) {
            int current = max(prevOne, prevTwo + value);
            prevTwo = prevOne;
            prevOne = current;
        }
        return prevOne;
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    vector<int> a(n);
    for (int &x : a)
        cin >> x;
    cout << Solution().rob(a) << '\n';
    return 0;
}
python
#!/usr/bin/env python3
from typing import List


class Solution:
    def rob(self, nums: List[int]) -> int:
        prev_two = prev_one = 0
        for value in nums:
            current = max(prev_one, prev_two + value)
            prev_two, prev_one = prev_one, current
        return prev_one


def main():
    n = int(input())
    a = list(map(int, input().split()))
    print(Solution().rob(a))


if __name__ == "__main__":
    main()

复杂度

  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(1)O(1)

总结

打家劫舍是线性 DP 的典型:状态只需"前一个"和"前两个",空间优化到 O(1)O(1)