题目描述
每个房子有一定的钱
- 条件 不能偷相邻房子的钱
- 条件 第一个房子和最后一个房子相邻,围成一个圆形,也就是不能同时偷第一个房子和最后一个房子的钱
解题思路
如果抢劫第一家,则不可以抢最后一家;否则,可以抢最后一家。因此,这个问题就转化成为了两趟动规,可以复用 “House Robber” 的代码。
对第一个房子到倒数第二个房子进行动态规划, 对第二个房子到最后一个房子进行动态规划,求两种情况下的最大值即可。
###动态规划
本次题目中的动态规划,每个位置处的能盗取的金额值最大值,只与前面两个位置有关,
dp[i] = max(dp[i-1]+nums[i], dp[i-1])
空间简化,使用两个变量记录前后两个位置的最大值,到最后一个位置时,取两个变量中的最大值即可
代码(自己的想法)
先按照House Robber 1中的常规动态规划算法处理到倒数第二个元素,得到一个最大值,然后判断最大值中是否包括第一个元素的情况,然后单独处理最后一个结果,
这种情况,就是考虑不全,还不如在开始的时候就考虑是否包括第一或最后一个元素
代码(Java)
public int solution_2(int []nums){
if(nums.length==1) return nums[0];
//两个元素的情况
if(nums.length==2) return Math.max(nums[0],nums[1]);
//三个元素的情况
return Math.max(robber(nums, 0,nums.length-1),robber(nums, 1,nums.length));
}
private int robber(int[] nums, int begin, int end){
//边界条件的处理情况
if (nums == null || begin >= end) return 0;
//只有三个元素的情况下
if(end-begin==1) return Math.max(nums[begin],nums[end]);
//四个元素以上的情况
int even,odd;
if(begin%2==0) {
even = nums[begin];
odd = Math.max(nums[begin+1],nums[begin]);
}
else
{
odd = nums[begin];
even = Math.max(nums[begin+1],nums[begin]);
}
for(int i=begin+2;i<end;++i) {
if (i % 2 == 0) {
even = Math.max(odd,even+nums[i]);
}
else
odd = Math.max(even,odd+nums[i]);
}
return Math.max(even,odd);
}
代码(Java)
对上述的代码进行简化处理,逻辑等情况
public int rob(int[] nums) {
if (nums.length == 1) return nums[0];
return Math.max(rob(nums, 0, nums.length - 2), rob(nums, 1, nums.length - 1));
}
private int rob(int[] num, int lo, int hi) {
int include = 0, exclude = 0;
for (int j = lo; j <= hi; j++) {
int i = include, e = exclude;
include = e + num[j];
exclude = Math.max(e, i);
}
return Math.max(include, exclude);
}
代码(c++)
维持三个位置处的变量,pre cur i 三个位置处的变量是相邻的,逐步移动即可,最后一个位置是最大值
class Solution {
public:
int rob(vector<int>& nums) {
int n = nums.size();
if (n < 2) return n ? nums[0] : 0;
return max(robber(nums, 0, n - 2), robber(nums, 1, n - 1));
}
private:
int robber(vector<int>& nums, int l, int r) {
int pre = 0, cur = 0;
for (int i = l; i <= r; i++) {
int temp = max(pre + nums[i], cur);
pre = cur;
cur = temp;
}
return cur;
}
};
复杂度
时间负责度为O(N),空间复杂度为O(1), 用两个变量逐步记录