在上次打劫完一条街道之后,窃贼又发现了一个新的可以打劫的地方,但这次所有的房子围成了一个圈,这就意味着第一间房子和最后一间房子是挨着的。每个房子都存放着特定金额的钱。你面临的唯一约束条件是:相邻的房子装着相互联系的防盗系统,且 当相邻的两个房子同一天被打劫时,该系统会自动报警。
给定一个非负整数列表,表示每个房子中存放的钱, 算一算,如果今晚去打劫,在不触动报警装置的情况下, 你最多可以得到多少钱 。
样例
Example1
Input: nums = [3,6,4]
Output: 6
Example2
Input: nums = [2,3,2,3]
Output: 6
注意事项
这题是House Robber的扩展,只不过是由直线变成了圈
解题思路:
Lintcode 392. 打劫房屋的升级版。
和第一版类似,不过此时分两种情况,
- 打劫第一栋房子,这样最后一栋不打劫
- 打劫第二栋房子,这样最后一栋可以打劫
所以使用两个dp数组来分别讨论,最后取两种情况的最大值
public class Solution {
/**
* @param nums: An array of non-negative integers.
* @return: The maximum amount of money you can rob tonight
*/
public int houseRobber2(int[] nums) {
// write your code here
if(nums==null || nums.length<=0)
return 0;
int n = nums.length;
//打劫第一间,则不打劫最后一间
int[] dp1 = new int[n];
dp1[0] = nums[0];
if(n>1)
dp1[1] = Math.max(nums[0],nums[1]);
for(int i=2; i<dp1.length; i++){
if(i == nums.length-1){
dp1[i] = dp1[i-1];
continue;
}
dp1[i] = Math.max(dp1[i-1], dp1[i-2] + nums[i]);
}
//不打劫第一间,则能打劫最后一间
int[] dp2 = new int[n];
dp2[0] = 0;
if(n>1)
dp2[1] = Math.max(0,nums[1]);
for(int i=2; i<dp2.length; i++)
dp2[i] = Math.max(dp2[i-1], dp2[i-2] + nums[i]);
return Math.max(dp1[dp1.length-1], dp2[dp2.length-1]);
}
}