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)
本文分享自微信公众号 - 架构说(JiaGouS),作者:王传义
原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。
原始发表时间:2018-04-25
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句