1. 问题分析与解题思路
这道题目描述了一个小偷在二叉树结构的房屋群中行窃的场景。每个节点代表一个房屋,节点值代表该房屋的财物价值。小偷需要遵守一个规则:不能同时偷窃直接相连的两个房屋(即父子节点不能同时被偷),否则会触发警报。
从算法角度看,这是一个典型的树形动态规划问题。我们需要在二叉树结构上计算最优解,同时满足特定约束条件。与线性结构的打家劫舍问题不同,树形结构增加了问题的复杂度,因为每个节点的决策会影响其子节点和父节点的选择。
1.1 动态规划状态定义
对于树中的每个节点,我们定义两种状态:
- 偷当前节点时的最大收益(robNow)
- 不偷当前节点时的最大收益(notRobNow)
这两种状态将作为我们动态规划的基础。通过后序遍历(左右根)的方式,我们可以自底向上地计算每个节点的这两种状态值。
1.2 状态转移方程
对于任意节点,其状态转移遵循以下规则:
-
如果偷当前节点,则不能偷其直接子节点:
robNow = node.val + left[1] + right[1]
(其中left[1]和right[1]分别表示不偷左右子节点时的最大收益) -
如果不偷当前节点,则可以自由选择是否偷子节点(取最优解):
notRobNow = max(left[0], left[1]) + max(right[0], right[1])
最终,根节点的最大收益就是max(robNow, notRobNow)。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 代码实现与解析
2.1 递归解法
java复制class Solution {
public int rob(TreeNode root) {
int[] res = robTree(root);
return Math.max(res[0], res[1]);
}
private int[] robTree(TreeNode node) {
if (node == null) {
return new int[]{0, 0};
}
int[] left = robTree(node.left);
