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.
打家劫舍 取非相邻元素求和最大,且认为第一个元素与最后一个元素相邻
举例:1 1 1 输出1
1 2 3 1 输出4
0 输出0
1 3 输出3
思路:标准的动态规划,和普通的House Robber.类似,因为第一个元素与最后一个元素不能同时取,所以分别对0-(n-2)与1-(n-1)各位元素取符合题意的最值,再取最大者。
代码写的很啰嗦,可以看Leetcode上的简洁版┗|`O′|┛ 嗷~~
class Solution {
int result = 0;
public int get(int[] nums ){
if(nums.length==0) return 0;
if(nums.length==1) return nums[0];
if(nums.length==2) return Math.max(nums[0],nums[1]);
int d[] = new int[nums.length+1];
d[0] = 0;
d[1] = nums[0];
d[2] = Math.max(nums[0],nums[1]);
for(int i = 3;i<=nums.length;i++){
d[i] = Math.max(d[i-1],d[i-2]+nums[i-1]);
}
return d[nums.length];
}
public int rob(int[] nums) {
if(nums.length==0) return 0;
if(nums.length==1) return nums[0];
if(nums.length==2) return Math.max(nums[0],nums[1]);
int[] a1 = new int[nums.length];
int[] a2 = new int[nums.length];
for(int i = 0;i<nums.length-1;i++){
a1[i] = nums[i];
a2[i] = nums[i+1];
}
return Math.max(get(a1),get(a2));
}
}
简化版本:
private int rob(int[] num, int lo, int hi) {
int include = 0, exclude = 0;//对于数组中的每一个元素,都包含两种选法:选取当前元素include,不选取当前元素exclude
for (int j = lo; j <= hi; j++) {
int i = include, e = exclude;//include表示选取当前元素的选法,exclude表示不选取当前元素的选法
include = e + num[j];//如果选取当前元素,那么就得选择没有选取前一元素的选法,因为相邻元素不能同时取
exclude = Math.max(e, i);//对于不选取当前元素的选法,应该是之前一步中总和最大的两种选法
}
return Math.max(include, exclude);/选择两种选法中最大的选法
}
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));
}