// 动态规划
class Solution {
public int rob(int[] nums) {
if (nums == null || nums.length == 0) return 0;
if (nums.length == 1) return nums[0];
if(nums.length == 2) return Math.max(nums[0],nums[1]);
int[][] dp = new int[nums.length][2];
int[] dp2 = new int[nums.length - 1];
dp[0][0] = nums[0];
dp[0][1] = 1;
if(nums[0] > nums[1]){
dp[1][0] = nums[0];
dp[1][1] = 1;
}else{
dp[1][0] = nums[1];
dp[1][1] = 2;
}
for (int i = 2; i < nums.length; i++) {
if(i != nums.length - 1){
if(dp[i - 1][0] > dp[i - 2][0] + nums[i]){
dp[i] = dp[i - 1];
}else{
dp[i][0] = dp[i - 2][0] + nums[i];
dp[i][1] = dp[i - 2][1];
}
}else{
if(dp[i - 2][1] == 1) dp[i][0] = Math.max(dp[i - 1][0],dp[i - 2][0] - nums[0] + nums[i]);
else dp[i][0] = Math.max(dp[i - 1][0],dp[i - 2][0] + nums[i]);
}
}
dp2[0] = nums[1];
dp2[1] = Math.max(nums[1],nums[2]);
for(int i = 2;i < nums.length - 1;i++){
dp2[i] = Math.max(dp2[i - 1],dp2[i - 2] + nums[i + 1]);
}
return Math.max(dp[nums.length - 1][0],dp2[nums.length - 2]);
}
}
思路比较复杂,dp[][]是处理了包含第一间房子的动态数组,考虑最后一间房子的最大值,dp2[]就是普通的打家劫舍,从第二间房子开始,最后一间房子就没有局限性了,比较两种情况的最大值即可。
// 动态规划
class Solution {
public int rob(int[] nums) {
if (nums == null || nums.length == 0) return 0;
if (nums.length == 1) return nums[0];
if(nums.length == 2) return Math.max(nums[0],nums[1]);
int[] dp1 = new int[nums.length - 1];
int[] dp2 = new int[nums.length - 1];
dp1[0] = nums[0];
dp1[1] = Math.max(nums[0],nums[1]);
for (int i = 2; i < nums.length - 1; i++) {
dp1[i] = Math.max(dp1[i - 2] + nums[i],dp1[i - 1]);
}
dp2[0] = nums[1];
dp2[1] = Math.max(nums[1],nums[2]);
for(int i = 2;i < nums.length - 1;i++){
dp2[i] = Math.max(dp2[i - 1],dp2[i - 2] + nums[i + 1]);
}
return Math.max(dp1[nums.length - 2],dp2[nums.length - 2]);
}
}
简单一些,不考虑末尾房子的情况中,如果出现最大值的组成中不包含第一间,那么这个情况在第二种情况中会被考虑完全,不存在漏考虑的情况。