题目描述:
解题思路:
这是一道简单的dp,转移方程是dp[i]=Math.max(dp[i-2]+nums[i],dp[i-1]);
当前偷窃到的金额等于前面[i-2]偷到的金额,加上这次要偷窃的,也就是说这次偷加上隔一个前面偷,或者这次不偷加上前一次偷,这两个情况取最大值。
参考代码:
public int rob(int[] nums) {
if(nums.length<=2){
if(nums.length<=1) return nums[0];
else return Math.max(nums[0],nums[1]);
}
int[] dp=new int[nums.length];
dp[0]=nums[0];
dp[1]=Math.max(nums[1],nums[0]);
for (int i = 2; i < nums.length; i++) {
dp[i]=Math.max(dp[i-2]+nums[i],dp[i-1]);
}
return dp[dp.length-1];
}
213. 打家劫舍 II
解题思路:
相较于第一个版本,房屋变成了一个圈,也就是说,取了第一个就不能取最后一个了。
思路就是将环形排列变成两次单排排列,第一次先计算取第一个房屋,不取最后一个房屋的情况下盗窃的最大值,然后再计算一下不取第一个,取最后一个房屋的情况下盗窃的最大值,最后的答案在这两个最大值之间取最大的即可。
参考代码:
public int rob(int[] nums) {
int len = nums.length;
if(len==1) return nums[0];
if(len==2) return Math.max(nums[0],nums[1]);
int dp[]=new int[len-1];
int max2=find(dp,nums,0,len-1);
Arrays.fill(dp,0);
int max1=find(dp,nums,1,len);
return Math.max(max1,max2);
}
private int find(int[] dp,int[] nums ,int start,int end){
dp[0]=nums[start];
dp[1]=Math.max(nums[start],nums[start+1]);
for (int i = 2; i < dp.length; i++) {
dp[i]=Math.max(dp[i-2]+nums[i+start],dp[i-1]);
}
return dp[dp.length-1];
}