【每日算法Day 106】打家劫舍系列最后一弹,撑住你就赢了!

网友投稿 224 2022-09-19

【每日算法Day 106】打家劫舍系列最后一弹,撑住你就赢了!

题目链接

LeetCode 337. 打家劫舍 III[1]

往期回顾:打家劫舍 I : 【每日算法Day 104】偷电瓶的周某今天放出来了,还不赶紧做这道题防范一下![2]

往期回顾:打家劫舍 II : 【每日算法Day 105】打家劫舍第二弹:看好你的电瓶车![3]

题目描述

在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为根。 除了根之外,每栋房子有且只有一个父房子与之相连。一番侦察之后,聪明的小偷意识到这个地方的所有房屋的排列类似于一棵二叉树。 如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警。

计算在不触动警报的情况下,小偷一晚能够盗取的最高金额。

示例1

输入:[3,2,3,null,3,null,1] 3 / \ 2 3 \ \ 3 1输出:7解释:小偷一晚能够盗取的最高金额 = 3 + 3 + 1 = 7.

示例2

输入:[3,4,5,1,3,null,1] 3 / \ 4 5 / \ \ 1 3 1输出:9解释:小偷一晚能够盗取的最高金额 = 4 + 5 = 9.

题解

这次是在一棵树上偷窃了,做法还是一样。对于结点 ​​r​​ 来说,我们还是分为偷和不偷两种情况。

如果偷的话,它的左右儿子就不能偷了,所以最大价值就是左儿子不偷的最大价值,加上右儿子不偷的最大价值,再加上 ​​r​​ 的价值。

而如果不偷的话,最大价值就是左儿子偷或不偷的最大价值,加上右儿子偷或不偷的最大价值。

因为需要用到儿子结点偷和不偷两个价值,所以需要在 ​​dfs​​​ 时返回两个值,用来表示偷和不偷两个最大价值,具体实现时用 ​​pair​​ 来表示。

可能有人会用另一种实现方式,用 ​​dfs0​​​ 表示不偷的最大价值,​​dfs1​​​ 表示偷的最大价值,然后两个函数互相调用。注意这样理论上是可行的,但是会产生很多重复计算,最终会超时。所以这种方法需要记忆化搜索,比较麻烦,需要用 ​​map​​ 来保存每个结点的答案。

代码

复杂实现方式(c++)

class Solution {public: unordered_map dp0, dp1; int dfs0(TreeNode* root) { if (!root) return 0; if (dp0.find(root) != dp0.end()) return dp0[root]; int res = 0; res += max(dfs0(root->left), dfs1(root->left)); res += max(dfs0(root->right), dfs1(root->right)); return dp0[root]=res; } int dfs1(TreeNode* root) { if (!root) return 0; if (dp1.find(root) != dp1.end()) return dp1[root]; int res = root->val; res += dfs0(root->left); res += dfs0(root->right); return dp1[root]=res; } int rob(TreeNode* root) { if (!root) return 0; dp0.clear(); dp1.clear(); return max(dfs0(root), dfs1(root)); }};

精简实现方式(c++)

class Solution {public: typedef pair pii; pii dfs(TreeNode* root) { if (!root) return {0, 0}; pii l = dfs(root->left); pii r = dfs(root->right); int r0 = max(l.first, l.second) + max(r.first, r.second); int r1 = l.first + r.first + root->val; return {r0, r1}; } int rob(TreeNode* root) { pii res = dfs(root); return max(res.first, res.second); }};

参考资料

[1]

LeetCode 337. 打家劫舍 III: ​​104】偷电瓶的周某今天放出来了,还不赶紧做这道题防范一下!: ​​105】打家劫舍第二弹:看好你的电瓶车!: ​​https://godweiyang.com/2020/04/19/leetcode-213/​​

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【每日算法Day 82】面试经典题:求第K大数,我写了11种实现,不来看看吗?
下一篇:IBM入职招聘信息 有兴趣看看
相关文章

 发表评论

暂时没有评论,来抢沙发吧~