1. 题目
读题
https://leetcode.cn/problems/house-robber-iii/description/
好的,我可以给你一个图形化的示例。假设我们有这样一个二叉树:
3
/ \
4 5
/ \ \
1 3 1
我们可以用一个表格来表示每个节点的f0和f1的值:
节点 | f0 | f1 |
---|---|---|
1 | 1 | 0 |
3 | 3 | 0 |
1 | 1 | 0 |
4 | 4 + max(0, 1) + max(0, 3) = 8 | max(1, 0) + max(3, 0) = 4 |
5 | 5 + max(0, 1) + max(0, 0) = 6 | max(1, 0) + max(0, 0) = 1 |
3 | 3 + max(4, 8) + max(1, 6) = 14 | max(8, 4) + max(6, 1) = 13 |
所以,最终的答案是max(f0(3), f1(3)) = max(14, 13) = 14。
考查点
这道题的考查点是:
- 如何用递归或动态规划来解决树形结构的问题。
- 如何定义合适的状态和状态转移方程来表示问题的最优解。
- 如何优化递归的效率,避免重复计算。
- 如何用不同的编程语言来实现算法。
2. 解法
思路
思路是这样的:
- 我们定义一个辅助函数helper,它接受一个树节点作为参数,返回一个长度为2的数组,表示抢劫或不抢劫该节点能得到的最大值。
- 如果节点为空,我们返回[0, 0],表示没有钱可抢。
- 如果节点不为空,我们先递归地计算它的左右子树的结果,分别存储在left和right数组中。
- 然后,我们计算抢劫当前节点的最大值,就是当前节点的值加上不抢劫左右子树的最大值,即root.val + left[1] + right[1]。
- 接着,我们计算不抢劫当前节点的最大值,就是抢劫或不抢劫左右子树的最大值之和,即Math.max(left[0], left[1]) + Math.max(right[0], right[1])。
- 最后,我们返回这两个值组成的数组。
这道题的状态转移方程是:
f_0(root) = root.val + f_1(root.left) + f_1(root.right)
f_1(root) = max(f_0(root.left), f_1(root.left)) + max(f_0(root.right), f_1(root.right))
其中,
$f_0(root)$表示抢劫当前节点的最大值,
$f_1(root)$表示不抢劫当前节点的最大值。
具体实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public int rob(TreeNode root) { if (root == null ) return 0 ; int [] result = helper(root); return Math.max(result[ 0 ], result[ 1 ]); } public int [] helper(TreeNode root) { if (root == null ) return new int [ 2 ]; int [] result = new int [ 2 ]; int [] left = helper(root.left); int [] right = helper(root.right); // result[0]表示抢劫当前节点的最大值 result[ 0 ] = root.val + left[ 1 ] + right[ 1 ]; // result[1]表示不抢劫当前节点的最大值 result[ 1 ] = Math.max(left[ 0 ], left[ 1 ]) + Math.max(right[ 0 ], right[ 1 ]); return result; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2019-05-01 java中的12种锁
2019-05-01 公平锁与非公平锁
2019-05-01 设计模式:门面模式(Facade)
2019-05-01 设计模式:装饰者模式
2019-05-01 设计模式:组合模式
2019-05-01 设计模式:桥接模式
2019-05-01 设计模式:适配器模式(Adapter)