LeetCode 213. House Robber II

题目描述

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.

在House Robber的基础上,这个题目增加的一个限制就是所有的房屋构成了一个环,在这种情况下保证任不偷盗任意两间相邻的房子。

解题思路

首先:如果房屋不构成一个圈,我们的解法有如下几种可能

  1. 头部和尾部的房屋都被抢劫

Alt text

  1. 头部房屋被抢劫,尾部房屋没有被抢劫

Alt text

  1. 头部房屋没有被抢劫,尾部的房屋被抢劫

Alt text

  1. 头部和尾部的房屋都没有被抢劫

Alt text 
  
如果房屋形成一个环,我们的最优解就只能选择后面的三种情况,第二种情况我们要保证最后一个房屋不能被抢劫,第三种情况要保证第一个房屋不能被抢劫,第四种情况已经包含在前两种情况中了。其实就是在环的连接处保证其中一个不被偷的情况下,求出从剩下的房屋中最多能盗取的金钱数目

因此在House Robber的基础上我们只要保证结果只能为上面第二和第三种情况即可。 
代码如下:

class Solution {
public int rob(int[] nums) {
if(nums == null || nums.length == 0) return 0;
if(nums.length == 1) return nums[0];
if(nums.length == 2) return Math.max(nums[0], nums[1]);
// 保证第一家安全和保证最后一家安全中的最大值
return Math.max(robMax(nums, 1, nums.length - 1), robMax(nums, 0, nums.length - 2));
}
public int robMax(int[] nums, int begin, int end){
int[] dp = new int[end - begin + 1];
dp[0] = nums[begin];
dp[1] = Math.max(nums[begin], nums[begin+1]);
for(int j=2; j<dp.length ; j++){
dp[j] = Math.max(dp[j-1], dp[j-2]+nums[j+begin]);
}
return dp[dp.length - 1];
}
}

  
上面代码的空间复杂度为O(n),我们发现其实不必把已经计算过的所有信息保存下来,只要保存后两个记录即可,优化后的空间复杂度为O(1),代码如下:

class Solution {
public int rob(int[] nums) {
if (nums.length == 1) return nums[0];
return Math.max(rob(nums, 1, nums.length - 1), rob(nums, 0, nums.length - 2));
}
private int rob(int[] nums, int lo, int hi) {
int include = 0, exclude = 0;
for (int j = lo; j <= hi; j++) {
int i = include, e = exclude;
include = e + nums[j];
exclude = Math.max(e, i);
}
return Math.max(include, exclude);
}
}

参考文章

Black_Knight:LeetCode 213. House Robber II

posted @ 2018-01-06 10:59  小丑进场  阅读(161)  评论(0)    收藏  举报