题目
思路
这个和198题相比,是多了一个限制条件,就是选了第一家就不能选最后一家。
所以假设p1是不偷最后一家时最大的偷窃金额,p2是不偷第一家是最大的偷窃金额,那最后的结果就是Math.max(p1,p2)。
p1,p2的计算就是两个198问题。
具体代码
class Solution {
public int rob(int[] nums) {
if(nums.length == 1){
return nums[0];
}
int p1 = stolen(nums,0);
int p2 = stolen(nums,nums.length-1);
return Math.max(p1,p2);
}
public int stolen(int[]nums,int x){
//注意:这里我原来想就是把不偷的第一家/最后一家的nums[i]置为0,但是nums是一个数组对象,是直接改变的,而不是改变副本,所以不可以这样赋值。
int dp[] = new int[nums.length+2];
for(int i = 0;i < nums.length;i++){
//于是改成这样,坐标相等,就加0,不改变原来nums[i]的值。
if(i == x){
dp[i+2] = Math.max(dp[i],dp[i+1]);
continue;
}
dp[i+2] = Math.max(dp[i]+nums[i],dp[i+1]);
}
return dp[nums.length+1];
}
}
看了一个leetcode题解,把空间复杂度降到O(1)
class Solution {
public int rob(int[] nums) {
if(nums.length == 0) return 0;
if(nums.length == 1) return nums[0];
return Math.max(myRob(Arrays.copyOfRange(nums, 0, nums.length - 1)),
myRob(Arrays.copyOfRange(nums, 1, nums.length)));
}
private int myRob(int[] nums) {
int pre = 0, cur = 0, tmp;
for(int num : nums) {
tmp = cur;
cur = Math.max(pre + num, cur);
pre = tmp;
}
return cur;
}
}