https://leetcode-cn.com/problems/house-robber/description/
你是一个专业的强盗,计划抢劫沿街的房屋。每间房都藏有一定的现金,阻止你抢劫他们的唯一的制约因素就是相邻的房屋有保安系统连接,如果两间相邻的房屋在同一晚上被闯入,它会自动联系警方。 给定一个代表每个房屋的金额的非负整数列表,确定你可以在没有提醒警方的情况下抢劫的最高金额。
首先是问题分解,假设当前已经肆虐过了前i个房子(0...i-1),且dp[i]是抢劫了下标为i的房子时的最大收益,那么可以得到状态转移方程: dp[i]=max(dp[i-1],dp[i-2]+nums[i]); i>2
class Solution {public: int rob(vector<int>& nums)
{
int size=nums.size(); if(size ==0)
{ return 0;
}else if(size ==1)
{ return nums[0];
}else if(size ==2)
{ return max(nums[0],nums[1]);
} int dp[size]={0}; //不知道啥情况
dp[0]=nums[0];
dp[1]=max(nums[0],nums[1]); for(int i=2;i<size;i++)
{
dp[i]=max(dp[i-1],dp[i-2]+nums[i]); //依赖前面的数据
} return dp[size-1];
}
};
https://leetcode.com/problems/house-robber-iii/discuss/79330/Step-by-step-tackling-of-the-problemhttp://zxi.mytechroad.com/blog/tree/leetcode-337-house-robber-iii/
打(1) 不打 打(3) 不打(1) 打(2 ) 不打(3)
具体来说:前三层是逻辑判断
func rob(root *TreeNode) int {
if root == nil {
return 0
}
//按照层次打劫 max(1不打劫 2打劫 3 不打劫 ,1打劫 2不打劫 3 打劫)
level2 := rob(root.Left) + rob(root.Right)
var level13 int = 0
if root.Left != nil {
level13 += rob(root.Left.Left) + rob(root.Left.Right)
}
if root.Right != nil {
level13 += rob(root.Right.Left) + rob(root.Right.Right)
}
level13 += root.Val
if level2 > level13 {
return level2
} else {
return level13
}
}
public int rob(TreeNode root) { if (root == null) return 0;
int val = 0;
if (root.left != null) {
val += rob(root.left.left) + rob(root.left.right);
}
if (root.right != null) {
val += rob(root.right.left) + rob(root.right.right);
}
return Math.max(val + root.val, rob(root.left) + rob(root.right));
}
递归缺点体现出来了 一个节点被会计算多次
计算0层时候 依赖 1层 和2层 计算1层时候 依赖 2层 和 3层计算2层时候 依赖 3层 和 4层节点 1 2 3 被计算2次
Time complexity: O(n^2)
Space complexity: O(n)