在这个问题中,你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

你是一个小偷,计划偷窃沿街的房屋,每个房屋里都有一定数量的现金。由于房屋之间装有警报器,如果你偷了相邻的两家,那么警报就会响。因此,你需要设计一个策略,确保不触发警报器的情况下,偷到最多的现金。
给定一个数组
,其中
表示第
个房屋中的现金数,你需要返回你在不触发警报的前提下能偷窃到的最高金额。
个房子的收益。
其中
表示偷到第
个房子时的最大金额。
;如果有两个房子,结果是
。
个房子,偷或不偷的最大金额为
nums[i])。
,即偷窃到最后一个房子的最大金额。
在递推过程中,我们注意到每次计算
只依赖于
和
,因此我们可以使用两个变量来代替整个
数组,节省空间。
,只需要遍历一次数组。
,只使用常量空间。
个房子的收益,不偷的话则直接沿用前一个房子的最大收益。
。
以上就是打家劫舍问题的基本思路。
class Solution:
def rob(self, nums: list[int]) -> int:
# 边界情况处理:如果房子数量为0或1
if not nums:
return 0
elif len(nums) == 1:
return nums[0]
# 初始化前两个房子的最大收益
prev2 = 0 # 表示前两个房子的收益
prev1 = nums[0] # 表示前一个房子的收益
# 从第三个房子开始计算到最后一个房子
for i in range(1, len(nums)):
# 当前房子的最大收益为:偷前两个房子加当前房子的收益,或者不偷这个房子,延续前一个房子的收益
current = max(prev1, prev2 + nums[i])
# 更新前两个房子的最大收益
prev2 = prev1
prev1 = current
# 最终返回偷窃到最后一个房子的最大收益
return prev1和
来存储偷前两个房子和前一个房子的最大收益,然后依次更新。
class Solution {
public:
int rob(vector<int>& nums) {
// 边界情况处理:如果房子数量为0或1
if (nums.empty()) return 0;
if (nums.size() == 1) return nums[0];
// 初始化前两个房子的最大收益
int prev2 = 0; // 表示前两个房子的收益
int prev1 = nums[0]; // 表示前一个房子的收益
// 从第三个房子开始计算到最后一个房子
for (int i = 1; i < nums.size(); ++i) {
// 当前房子的最大收益为:偷前两个房子加当前房子的收益,或者不偷这个房子,延续前一个房子的收益
int current = max(prev1, prev2 + nums[i]);
// 更新前两个房子的最大收益
prev2 = prev1;
prev1 = current;
}
// 最终返回偷窃到最后一个房子的最大收益
return prev1;
}
};nums[i]),通过选择偷或不偷当前房子,来最大化收益。
,通过两个变量 prev1 和 prev2 存储前两个房子的最大收益。
,只需遍历一次数组。