LeetCodehot 力扣热图100 打家劫舍

问题分析

题目是 打家劫舍(House Robber),给定一个整数数组 nums,其中 nums[i] 代表第 i 间房子里的现金。

• 你不能 连续 偷两间相邻的房子,否则会触发警报。

• 目标是 求能够偷到的最大金额

解题思路

使用 动态规划(Dynamic Programming, DP) 解决:

1. 定义状态 dp[i]

• dp[i] 代表在 前 i 个房子 中,能偷到的最大金额。

2. 状态转移方程

• 对于第 i 个房子,有 两种选择

不偷 第 i 间房子 → 保持 dp[i-1]

第 i 间房子 → 获得 nums[i-1],并加上 dp[i-2](因为不能偷相邻房子)

• 取最大值:

3. 初始化

• 只有一间房子 nums[0],最大金额就是 nums[0]。

• dp[1] = nums[0]

• dp[2] = max(nums[0], nums[1])(两间房子,偷金额较大的那间)

4. 最终答案

• dp[n] 代表能偷的最大金额。

代码解析

class Solution {
public:
    int rob(vector<int>& nums) {
        if(nums.size() == 1) return nums[0]; // 只有一间房子,直接返回

        vector<int> dp(nums.size() + 1); // dp 数组
        dp[1] = nums[0]; // 偷第一间房子
        dp[2] = max(nums[0], nums[1]); // 偷第一间或第二间的较大值

        for(int i = 3; i <= nums.size(); i++) {
            dp[i] = max(dp[i - 1], nums[i - 1] + dp[i - 2]); // 状态转移方程
        }

        return dp[nums.size()]; // 返回最后一个房子的最大金额
    }
};

运行步骤

假设输入:

nums = {2, 7, 9, 3, 1}

Step 1: 初始化

房子编号

现金 nums[i]

dp[i] 计算方式

结果

1

2

dp[1] = nums[0]

2

2

7

dp[2] = max(nums[0], nums[1]) = max(2, 7)

7

Step 2: 动态规划填表

房子编号 i

nums[i-1]

计算 dp[i]

结果

3

9

dp[3] = max(dp[2], dp[1] + nums[2]) = max(7, 2 + 9) = 11

11

4

3

dp[4] = max(dp[3], dp[2] + nums[3]) = max(11, 7 + 3) = 11

11

5

1

dp[5] = max(dp[4], dp[3] + nums[4]) = max(11, 11 + 1) = 12

12

Step 3: 最终结果

dp[5] = 12,表示最大可偷金额为 12。

时间复杂度分析

• dp[i] 依赖于 dp[i-1] 和 dp[i-2],遍历 nums 一次,时间复杂度为:

• dp 数组占 O(n) 额外空间,优化后可用 O(1) 额外空间(优化见下)。

优化

我们只需要 dp[i-1] 和 dp[i-2],可以用 两个变量 代替 dp 数组,降低空间复杂度:

class Solution {
public:
    int rob(vector<int>& nums) {
        if(nums.size() == 1) return nums[0];

        int prev2 = nums[0]; // 相当于 dp[i-2]
        int prev1 = max(nums[0], nums[1]); // 相当于 dp[i-1]
        int curr = prev1;

        for(int i = 2; i < nums.size(); i++) {
            curr = max(prev1, prev2 + nums[i]);
            prev2 = prev1;
            prev1 = curr;
        }

        return curr;
    }
};

时间复杂度: O(n)(遍历 nums 一次)

空间复杂度: O(1)(只使用三个变量)

总结

1. 状态定义: dp[i] 为前 i 个房子的最大可偷金额。

2. 状态转移方程: dp[i] = max(dp[i-1], dp[i-2] + nums[i-1])。

3. 时间复杂度 O(n),空间复杂度可优化至 O(1)。

4. 滚动数组优化,只用两个变量存 dp[i-1] 和 dp[i-2],节省空间。 🚀

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值