213. House Robber II
1、Description
2、题解思路
该问题和之前的House Robber I问题基本类似,只不过多了一个小变化,就是所有的城市现在围成一个环状,也就是多了个限制:不允许数组头尾的两家银行同时被盗。由House Robber I不难得到递推方程,其中rob[i]表示从城市0抢到城市i所能得到的最大金额。那么问题来了如何在House Robber I的基础上进行改进呢,最直观的就是由于头尾元素之间是互斥的,那么我们就利用上述递推方程连续求解两次,一次去掉头城市,一次去掉尾城市。然后取两次求解中的最大值即可.
3、代码实现(java)
代码的基本操作只用到了一层for循环,时间复杂度为O(n),额外开辟一个数组rob,空间复杂度为O(n)
class Solution {
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]);
if(nums.length==3) return Math.max(Math.max(nums[0],nums[1]),nums[2]);
int[] rob = new int[nums.length-1];
//remove the head
rob[0] = nums[1];
rob[1] = Math.max(rob[0],nums[1+1]);
for(int i = 2;i<nums.length-1;i++){
rob[i] = Math.max(rob[i-2]+nums[i+1],rob[i-1]);
}
int removehead = rob[nums.length-2];
// System.out.println(Arrays.toString(rob));
//remove the tail
rob[0] = nums[0];
rob[1] = Math.max(rob[0],nums[1]);
for(int i = 2;i<nums.length-1;i++){
rob[i] = Math.max(rob[i-2]+nums[i],rob[i-1]);
}
int removetail = rob[nums.length-2]; //System.out.println(Arrays.toString(rob));
return Math.max(removehead,removetail);
}
}