抢了i元素就不能抢i-1和i+1,属于比较好想的动规。dp[i]存放[0,i]子数组的最大抢劫金额,递推公式为 dp[i] = max(dp[i-1], dp[i-2] + nums[i])。取抢或不抢当前节点的最大值。
class Solution {
public int rob(int[] nums) {
if(nums.length == 1) {
return nums[0];
}
if(nums.length == 2) {
return Math.max(nums[0], nums[1]);
}
int[] dp = new int[nums.length];
dp[0] = nums[0];
dp[1] = Math.max(nums[0], nums[1]);
for(int i=2; i<nums.length; i++) {
dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i]);
}
return dp[nums.length - 1];
}
}
环的情况没总结好。可以只取前i-1个节点,无环,再取后i-1个节点,也无环。等于跑两次打家劫舍1,取最大值。 还有一种情形是既不取头也不取尾,那么被前两种情况覆盖。
class Solution {
public int rob(int[] nums) {
int[] dp = new int[nums.length - 1];
int len = nums.length;
if(len == 1) {
return nums[0];
}
if(len == 2) {
return Math.max(nums[0], nums[1]);
}
if(len == 3) {
return Math.max(nums[0], Math.max(nums[1], nums[2]));
}
dp[0] = nums[0];
dp[1] = Math.max(nums[0], nums[1]);
for(int i=2; i<len-1; i++) {
dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i]);
}
int m1 = dp[dp.length - 1];
for(int i=0; i<dp.length; i++) {
dp[i] = 0;
}
dp[0] = nums[1];
dp[1] = Math.max(nums[1], nums[2]);
for(int i=3; i<len; i++) {
dp[i-1] = Math.max(dp[i-2], dp[i-3] + nums[i]);
}
int m2 = dp[dp.length - 1];
return Math.max(m1, m2);
}
}
337. House Robber III 在树上做动规,以前没做过。属于想不出的思路。dp数组只有两个元素,一个偷一个不偷,存放最大钱数。配合递归,在每层上都等于保留当前节点偷与不偷的最大钱数。 递推公式为:要么取当前节点,则左右子节点都不能取。 要么不取当前节点,则可以取左右子节点。 递归函数返回当前节点的dp数组。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int[] robDp(TreeNode root) {
int[] res = new int[2];
if(root == null) {
return res;
}
int[] left = robDp(root.left);
int[] right = robDp(root.right);
res[1] = root.val + left[0] + right[0];
res[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
return res;
}
public int rob(TreeNode root) {
if(root == null) {
return 0;
}
int[] res = robDp(root);
return Math.max(res[0], res[1]);
}
}