213. House Robber II
Total Accepted: 23996 Total Submissions: 80010 Difficulty: Medium
Note: This is an extension of House Robber.
After robbing those houses on that street, the thief has found himself a new place for his thievery so that he will not get too much attention. This time, all houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, the security system for these houses remain the same as for those in the previous street.
Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.
题目描述
本题目是在LeetCode#198题的基础上的变体,此时小偷需要抢钱的房间是环状,不能偷相邻的两个房间,一偷相邻房间就触发报警。给定一列非负整数,代表每间房屋的金钱数,计算出在不惊动警察的前提下一晚上最多可以打劫到的金钱数。
环状房间:意味着如果选择偷了第一个房间,那么必然不能选择偷最后一个房间;如果选择偷了最后一个房间,那么必然不能选择偷第一个房间。
解题思路
(1)对于第i个房间我们的选择是偷和不偷, 如果决定是偷 则第i-1个房间必须不偷 那么 这一步的就是 maxmoney[i]=maxmoney[i-2]+nums[i]; 假设maxmoney[i]表示到达第i个房间编号时所抢的最大金额;如果是不偷, 那么上一步就无所谓是不是已经偷过, maxmoney[i]= maxmoney[i -1 ], 因此maxmoney[i]=max(maxmoney[i-2]+nums[i],maxmoney[i-1]);
(2)动态规划,状态转移方程:maxmoney[i]=max(maxmoney[i-2]+nums[i],maxmoney[i-1]);
(3)需要分成两种情况,由于不能同时选择第一个房间和最后一个房间,分成两种情况:
Case1:选择抢了第一间房间,不抢最后一间房间的情况下最大金额;
Case2:选择不抢第一间房间,抢了最后一间房间的情况下最大金额;
然后最后比较两者的最大值即为最终最大金额。
C++代码
class Solution {
public:
int rob(vector<int>& nums) {
int n=nums.size();
if(n==0)return 0;
else if(n==1)return nums[0];
else{
//由于不能同时选择第一个房间和最后一个房间
//分成两种情况
int Maxmoney1;//Case1:选择抢了第一间房间,不抢最后一间房间的情况下最大金额
int Maxmoney2;//Case2:选择不抢第一间房间,抢了最后一间房间的情况下最大金额
//Case1:
vector<int> maxmoney(n,0);
maxmoney[0]=nums[0];
maxmoney[1]=nums[0];
for(int i=2;i<n-1;i++)
maxmoney[i]=max(maxmoney[i-2]+nums[i],maxmoney[i-1]);
maxmoney[n-1]=maxmoney[n-2];
Maxmoney1=maxmoney[n-1];
//Case2:
maxmoney[0]=0;
maxmoney[1]=nums[1];
for(int i=2;i<n;i++)
maxmoney[i]=max(maxmoney[i-2]+nums[i],maxmoney[i-1]);
Maxmoney2=maxmoney[n-1];
return max(Maxmoney1,Maxmoney2);
}
}
};