问题描述:
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 robberI的问题,是通过DP算法实现的。那这道题的难点在于它构成一个环,所以导致了不知道起点在哪里。起初,我想能不能把环从某个点拆开,发现做不到,因为每个点的取值都由它之前的一个或两个点决定。
后来想到了干脆每个点都做为起始点试试,时间复杂度为O(N2),空间复杂度为O(N),后来又想能不能用二维 DP解决,发现二维DP并不能有效,因为当换个新的起点时,和上个起点获得的数据并不能产生什么联系,所以干脆使用O(n2)的方法试试,结果AC
代码如下:260ms
public class Solution {
public int rob(int[] nums) {
int length=nums.length;
if(length<=0)
return 0;
int[] tmpNums = new int[length];
int max = 0;
for(int i = 0;i<length;i++){
tmpNums[i] = nums[i];
for(int j = 1;j<length-1;j++){
int index = (i+j)%length;
int val = nums[index];
if(j>1)
val+=tmpNums[(index+length-2)%length];
tmpNums[index] = Math.max(tmpNums[(index-1+length)%length],val);
}
int tmpMax = tmpNums[(i+length-2)%length];
if(tmpMax>max)
max = tmpMax;
}
return max;
}
}
看了网上的介绍,他们只进行了两次遍历,第一次是从第一个遍历到倒数第二个,第二次是从第二个遍历到倒数第一个。那从第三个遍历和从第一个遍历是等价的吗?我脑容量小,想不明白.
代码如下:288ms
public class Solution {
public int rob(int[] nums) {
int length = nums.length;
int max = 0;
if(length<=2){
for(int i = 0;i<length;i++){
if(nums[i]>max)
max = nums[i];
}
return max;
}
int[] tmpNums = new int[length];
tmpNums[0] = nums[0];
for(int i = 1;i<length-1;i++){
int val = nums[i];
if(i>1)
val+=tmpNums[i-2];
tmpNums[i] = Math.max(val,tmpNums[i-1]);
}
if(tmpNums[length-2]>max)
max = tmpNums[length-2];
tmpNums[1] = nums[1];
for(int i = 2;i<length;i++){
int val = nums[i];
if(i>2)
val+=tmpNums[i-2];
tmpNums[i] = Math.max(val,tmpNums[i-1]);
}
if(tmpNums[length-1]>max)
max = tmpNums[length-1];
return max;
}
}