//你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的
//房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。
//
// 给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下 ,今晚能够偷窃到的最高金额。
//
// 示例 1:
//
//输入:nums = [2,3,2]
//输出:3
//解释:你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。
//
//
// 示例 2:
//
//
//输入:nums = [1,2,3,1]
//输出:4
//解释:你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3)。
// 偷窃到的最高金额 = 1 + 3 = 4 。
思路: 动态规划,假设数组有 i-2 或 i-1 个元素且这i-2个和i-1房屋的最优解已经得出,则当有第i家时对应两种情况:抢(nums[i-2] + nums[i])或不抢(nums[i-1]),则第i家的最优解为 dp[i] = Math.max(nums[i-1], nums[i-2]+num[i]);
public class DynamicRob {
public static void main(String[] args) {
int[] nums = new int[]{1,2,3,1};
Integer max = rob2(nums);
System.out.println(max);
}
/**
* 打家劫舍1
* 街道
* @param nums
* @return
*/
public Integer rob1(int[] nums) {
//动态规划
// dp[i] = Math.max(dp[i-2]+nums[i], dp[i-1]);
if (null == nums) {
return 0;
}
int length = nums.length;
if (length == 1) { return nums[0]; }
int[] dp = new int[length+1];
dp[0] = 0;
dp[1] = nums[0];
for (int i = 2; i<nums.length; i++) {
dp[i] = Math.max(dp[i-2] + nums[i-1], dp[i-1]);
}
return dp[length];
}
/**
* 环
* @param nums
* @return
*/
public static Integer rob2(int[] nums) {
//动态规划 dp[i] = Math.max(dp[i-2]+nums[i], dp[i-1]);
if (null == nums) {
return 0;
}
int length = nums.length;
if (length == 1) { return nums[0]; }
int[] dp = new int[length]; //第一家打
dp[0] = 0;
dp[1] = nums[0];
for (int i = 2; i<nums.length; i++) {
dp[i] = Math.max(dp[i-2] + nums[i-1], dp[i-1]);
}
int[] dp2 = new int[length+1]; //第一家不打
dp2[0] = 0;
dp2[1] = 0;
for (int i = 2; i<nums.length; i++) {
dp2[i] = Math.max(dp2[i-2] + nums[i-1], dp2[i-1]);
}
return Math.max(dp[length-1], dp2[length]);
}
/**
* 二叉树
* @param root
* @return
*/
public Integer rob3(TreeNode root) {
if (null == root) {
return 0;
}
Integer res1 = 0;
res1 += root.val; //根在结果中
if (null != root.left) {
res1 += rob3(root.left.left) + rob3(root.left.right);
}
if (null != root.right) {
res1 += rob3(root.right.left) + rob3(root.right.right);
}
Integer res2 = 0; //根不在结果中
res2 += rob3(root.left) + rob3(root.right);
return Math.max(res1, res2);
}
}