题目描述:你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。
方法1:动态规划,第一圈和最后一圈不能同时偷,要么第一家到倒数第二家,要么第二家到最后一家,相当于做两次打家劫舍Ⅰ
class Solution {
public:
int rob(vector<int>& nums) {
int p = nums[0];
if(nums.size() == 1)return p;
int q = nums[1];
int max1 =max(p,q);//从第一个房间到倒数第二个房间能得最高金额
if(nums.size() == 2)return max1;
int m1 = 0;
for(int i=2;i<nums.size()-1;i++){
m1 = max(p+nums[i],q);
p = q;
q = m1;
max1 = max(max1,m1);
}
p = nums[1];
q = nums[2];
int max2 = max(p,q);//从第二个房间到最后一个房间能得最高金额
int m2 = 0;
for(int i=3;i<nums.size();i++){
m2 = max(p+nums[i],q);
q = q;
q = m2;
max2 = max(max2,m2);
}
return max(max1,max2);
}
};
出错,无法通过所有样例,逻辑出现错误,第二个房间偷的最大值应该是4,而不是1
修改,从带一个房间开始偷,q 初始值应该是max(p,nums[1]),从第二个房间开始,q 初始值应该是max(p,nums[2])
class Solution {
public:
int rob(vector<int>& nums) {
int p = nums[0];
if(nums.size() == 1)return p;
int q = max(p,nums[1]);
int max1 =max(p,q);//从第一个房间到倒数第二个房间能得最高金额
if(nums.size() == 2)return max1;
int m1 = 0;
for(int i=2;i<nums.size()-1;i++){
m1 = max(p+nums[i],q);
p = q;
q = m1;
max1 = max(max1,m1);
}
p = nums[1];
q = max(p,nums[2]);
int max2 = q;//从第二个房间到最后一个房间能得最高金额
int m2 = 0;
for(int i=3;i<nums.size();i++){
m2 = max(p+nums[i],q);
p = q;
q = m2;
max2 = max(max2,m2);
}
return max(max1,max2);
}
};