Medium
题目描述
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,一夜之内能够偷窃到的最高金额。
示例 1:
输入:nums = [1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
偷窃到的最高金额 = 1 + 3 = 4 。
示例 2:
输入:nums = [2,7,9,3,1]
输出:12
解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
偷窃到的最高金额 = 2 + 9 + 1 = 12 。
提示:
1 <= nums.length <= 1000 <= nums[i] <= 400
解题思路
这是一道经典的动态规划题目。核心思想是对于每个房屋,我们需要决定是否偷窃,而这个决定会影响到后续的选择。
分析过程:
对于第 i 个房屋,我们有两种选择:
- 偷窃第 i 个房屋:那么我们不能偷窃第 i-1 个房屋,最大收益为
nums[i] + dp[i-2] - 不偷窃第 i 个房屋:最大收益为
dp[i-1]
因此状态转移方程为:dp[i] = max(dp[i-1], nums[i] + dp[i-2])
优化思路:
由于每个状态只依赖于前两个状态,我们可以使用两个变量来优化空间复杂度,将 O(n) 的空间复杂度优化到 O(1)。
这种方法既简洁又高效,是解决此类"不能选择相邻元素"问题的标准模板。
代码实现
class Solution {
public:
int rob(vector<int>& nums) {
if (nums.empty()) return 0;
if (nums.size() == 1) return nums[0];
int prev2 = nums[0];
int prev1 = max(nums[0], nums[1]);
for (int i = 2; i < nums.size(); i++) {
int current = max(prev1, nums[i] + prev2);
prev2 = prev1;
prev1 = current;
}
return prev1;
}
};
class Solution:
def rob(self, nums: List[int]) -> int:
if len(nums) == 1:
return nums[0]
prev2 = nums[0]
prev1 = max(nums[0], nums[1])
for i in range(2, len(nums)):
current = max(prev1, nums[i] + prev2)
prev2 = prev1
prev1 = current
return prev1
public class Solution {
public int Rob(int[] nums) {
if (nums.Length == 1) return nums[0];
int prev2 = nums[0];
int prev1 = Math.Max(nums[0], nums[1]);
for (int i = 2; i < nums.Length; i++) {
int current = Math.Max(prev1, nums[i] + prev2);
prev2 = prev1;
prev1 = current;
}
return prev1;
}
}
var rob = function(nums) {
if (nums.length === 1) return nums[0];
let prev2 = nums[0];
let prev1 = Math.max(nums[0], nums[1]);
for (let i = 2; i < nums.length; i++) {
let current = Math.max(prev1, prev2 + nums[i]);
prev2 = prev1;
prev1 = current;
}
return prev1;
};
复杂度分析
| 复杂度类型 | 大小 |
|---|---|
| 时间复杂度 | O(n) |
| 空间复杂度 | O(1) |
相关题目
152. Maximum Product Subarray (Medium)
213. House Robber II (Medium)
337. House Robber III (Medium)
740. Delete and Earn (Medium)
2560. House Robber IV (Medium)
2611. Mice and Cheese (Medium)
2789. Largest Element in an Array after Merge Operations (Medium)
3840. House Robber V (Medium)