1. 题目解析与问题建模
今天我们来解决LeetCode上经典的二叉树打家劫舍问题(337题)。这个问题将传统的动态规划问题移植到了二叉树结构上,增加了不少趣味性。题目描述是这样的:一个小偷要在一棵二叉树的房屋结构中行窃,如果两个直接相连的房屋(即父子节点)在同一天晚上被打劫,系统就会报警。我们的任务是计算小偷在不触发警报的情况下能够盗取的最大金额。
1.1 问题特点分析
这个问题有几个关键特征需要注意:
- 房屋排列成二叉树结构,每个节点代表一个房屋,节点值代表该房屋的金额
- 不能同时抢劫相邻的父子节点,否则会触发警报
- 需要计算所有可能的抢劫组合,找出金额最大的方案
与线性结构的打家劫舍问题相比,二叉树结构带来了新的挑战。在线性结构中,我们只需要考虑前一个节点是否被抢劫,而在二叉树中,我们需要同时考虑左右子节点的情况。
1.2 示例分析
让我们仔细看看题目给出的两个示例:
示例1:
输入:root = [3,2,3,null,3,null,1]
code复制 3
/ \
2 3
\ \
3 1
最优解:3 + 3 + 1 = 7
解释:选择抢劫根节点(3)、右子节点(3)和右子节点的右子节点(1)
示例2:
输入:root = [3,4,5,1,3,null,1]
code复制 3
/ \
4 5
/ \ \
1 3 1
最优解:4 + 5 = 9
解释:选择抢劫左子节点(4)和右子节点(5)
从这两个例子可以看出,最优解有时需要跳过某些节点,有时又需要连续选择多个节点,关键在于如何找到不违反规则的最大金额组合。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 解题思路与算法设计
2.1 动态规划思路
这个问题非常适合用动态规划来解决。我们需要为每个节点定义两种状态:
- 选择当前节点时的最大收益
- 不选择当前节点时的最大收益
对于二叉树中的每个节点,我们可以递归地计算这两种状态的值,然后根据子节点的状态来决定当前节点的最优解。
2.2 状态转移方程
定义:
- dp[0]:不选择当前节点时的最大收益
- dp[1]:选择当前节点时的最大收益
状态转移关系如下:
- 如果选择当前节点,那么
