Day47题目
LeetCode198.打家劫舍1
核心思想:dp[i]=Math.max(dp[i-1],dp[i-2]+nums[i]),每一项是前一项或者前前一项+自身的最大值
class Solution {
public int rob(int[] nums) {
if (nums.length == 1)
return nums[0];
int[] dp = new int[nums.length + 1];
dp[0] = nums[0];
dp[1] = Math.max(dp[0], nums[1]);
for (int i = 2; i < nums.length; i++) {
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
}
return Math.max(dp[nums.length - 1], dp[nums.length - 2]);
}
}
LeetCode213打家劫舍2
核心思想:这里需要从第一个到倒数第二个之间和第二个到最后一个,这两种情况用打家劫舍1的方法计算结果,然后取其中最大的
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 res1 = robRoom(nums,0,nums.length-2);
int res2 = robRoom(nums,1,nums.length-1);
return Math.max(res1,res2);
}
public int robRoom(int[] nums,int start, int end){
if (end == start) return nums[start];
int[] dp = new int[nums.length+1];
dp[start] = nums[start];
dp[start+1] = Math.max(nums[start],nums[start+1]);
for(int i= start+2 ; i <= end ; i ++){
dp[i] = Math.max(dp[i-1],dp[i-2]+nums[i]);
}
return dp[end];
}
}
LeetCode337打家劫舍3
核心思想:变成了树,使用的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 rob(TreeNode root) {
int[] res = robRoom(root);
return res[0]> res[1] ? res[0] : res[1];
}
public int[] robRoom(TreeNode node){
int[] res = new int[2];
if(node == null){
return res;
}
int[] left = robRoom(node.left);
int[] right = robRoom(node.right);
// 计算选当前节点的最大值和不选的最大值
res[0] = Math.max(left[0],left[1]) + Math.max(right[1],right[0] );
res[1] = left[0]+right[0]+node.val;
return res;
}
}