打家劫舍V-LeetCode
3840. 打家劫舍 V - House Robber V
🎯 问题描述(来源于LeetCode)
描述:
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,每间房还有一个颜色代码。
与传统的打家劫舍不同,本题的限制为:相邻且颜色相同的房屋不能在同一晚上被偷。
即:如果两间相邻的房屋颜色不同,则可以同时偷窃;如果颜色相同,则不能同时偷窃。
给定两个数组 nums(金额)和 colors(颜色),返回不触发警报的情况下能偷窃到的最大金额。
说明:
- 相邻房屋之间只有颜色相同时才有额外限制。
- 数组长度
1 <= n <= 10^5。
示例:
- 示例 1:
1 | 输入: nums = [1,4,3,5], colors = [1,1,2,2] |
- 示例 2:
1 | 输入: nums = [3,1,2,4], colors = [2,3,2,2] |
💻 解题思路
思路:动态规划(按您的代码)
算法步骤
- 获取房屋数量
n,创建dp数组,dp[i]表示考虑前i+1间房屋(下标 0…i)能获得的最大金额。 - 处理第一间房屋(
i=0):dp[0] = nums[0]。 - 处理第二间房屋(
i=1):- 判断
colors[0] == colors[1]。 - 若相同,则不能同时偷,取
max(dp[0], nums[1])。 - 若不同,则可以同时偷,取
dp[0] + nums[1]。
- 判断
- 对于
i >= 2:- 判断
colors[i-1] == colors[i]。 - 若不同,则当前房屋可以与前一个同时偷:
dp[i] = dp[i-1] + nums[i]。 - 若相同,则当前房屋不能与前一个同时偷,需要比较两种情况:偷当前房屋则加上
dp[i-2] + nums[i],不偷则保持dp[i-1],取最大值。
- 判断
- 返回
dp[n-1]。
代码实现
1 | from typing import List |
📊 性能分析
- 时间复杂度:,一次遍历。
- 空间复杂度:,使用了
dp数组。可优化到 (只保留前两个状态)。
思考
代码正确实现了题目要求的状态转移,逻辑清晰:分别处理了 i=0, i=1 和 i>=2 的情况,并根据相邻颜色是否相同来决定转移方程。
优点:直接对应问题定义,易于理解。
可优化点:可以使用滚动变量代替数组,降低空间复杂度至 。另外,对于 i=1 的情况,可以用统一的转移公式 dp[i] = max(dp[i-1], dp[i-2] + nums[i]) 并在颜色相同时禁止同时偷,但手动分支同样正确。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 笺札!






