198. 打家劫舍,不难
递推公式:
dp[i] = Math.max(dp[i-2]+nums[i],dp[i-1]);
public int rob(int[] nums) {
if(nums.length==1)return nums[0];
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-2]+nums[i],dp[i-1]);
}
return dp[dp.length-1];
}
213. 打家劫舍 II
在上一题的基础上,本题加了一个新的设定,就是环,从这种问题上来说的话可以分类讨论,就是带不带首尾,分两类比较一下大小即可代码如下:
public int rob(int[] nums) {
if(nums.length==1)return nums[0];
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-1;i++){
dp[i] = Math.max(dp[i-2]+nums[i],dp[i-1]);
}
int count1 = dp[dp.length-2];
dp[0] = 0;
dp[1] = nums[1];
for(int i=2;i<nums.length;i++){
dp[i] = Math.max(dp[i-2]+nums[i],dp[i-1]);
}
return Math.max(dp[dp.length-1],count1);
}
337. 打家劫舍 III
树形dp,很有意思,每个节点分一个长度为2的dp数组,第一个维度代表了偷当前节点,第二个代表不偷当前节点,然后后序遍历代码如下:
public int rob(TreeNode root) {
int[] re = robtree(root);
return Math.max(re[0],re[1]);
}
public int[] robtree(TreeNode root){
int [] dp = new int[2];
if(root==null)return dp;
int [] left = robtree(root.left);
int [] right = robtree(root.right);
dp[1] = root.val+left[0]+right[0];
dp[0] = Math.max(left[0],left[1])+Math.max(right[0],right[1]);
return dp;
}