二叉树的坡度-LeetCode
563. 二叉树的坡度 - Binary Tree Tilt
🎯 问题描述(来源于LeetCode)
描述:
给定一个二叉树的根节点 root,计算并返回整个树的坡度。
一个节点的坡度定义为:该节点左子树所有节点之和与右子树所有节点之和的差的绝对值。
空节点的坡度为 0。
整棵树的坡度是所有节点坡度之和。
说明:
- 子树和包括该节点及其所有后代节点。
- 坡度不包含节点自身的值,只计算左右子树和的差。
示例:
- 示例 1:
1 | 输入: root = [1,2,3] |
- 示例 2:
1 | 输入: root = [4,2,9,3,5,null,7] |
💻 解题思路
思路1:后序遍历 + 重复计算子树和
算法步骤
-
定义辅助函数
getSum(node):- 返回以
node为根的子树所有节点值之和。 - 递归终止:如果
node为None,返回0。 - 否则返回
getSum(node.left) + getSum(node.right) + node.val。
- 返回以
-
主函数
findTilt(root):- 如果
root为None,返回0。 - 递归计算左子树的坡度:
findTilt(root.left) - 递归计算右子树的坡度:
findTilt(root.right) - 计算当前节点的坡度:
abs(getSum(root.left) - getSum(root.right)) - 返回三者之和。
- 如果
思路1:代码实现
1 | # Definition for a binary tree node. |
思路1:📊 性能分析
- 时间复杂度:,每个节点调用
getSum遍历其所有子孙节点,存在大量重复计算。 - 空间复杂度:,递归栈深度为树高。
思路2:后序遍历 + 同时返回子树和与累计坡度(优化)
算法步骤
-
定义递归函数
dfs(node):- 返回值:元组
(子树和, 以该节点为根的累计坡度)。 - 递归终止:如果
node为None,返回(0, 0)。
- 返回值:元组
-
递归计算左右子树:
- 得到
(left_sum, left_tilt)=dfs(node.left) - 得到
(right_sum, right_tilt)=dfs(node.right)
- 得到
-
计算当前节点信息:
- 当前子树和:
cur_sum = left_sum + right_sum + node.val - 当前节点坡度:
cur_tilt = abs(left_sum - right_sum) - 累计总坡度:
total_tilt = left_tilt + right_tilt + cur_tilt
- 当前子树和:
-
返回元组
(cur_sum, total_tilt)。 -
主函数:调用
dfs(root),返回结果元组的第二个元素(总坡度)。
思路2:代码实现
1 | # Definition for a binary tree node. |
思路2:📊 性能分析
- 时间复杂度:,每个节点只被访问一次,所有计算为 。
- 空间复杂度:,递归栈深度为树高(最坏情况 )。
思考
- 思路1 直观但效率低,思路2 通过后序遍历将子树和与坡度同时向上传递,避免了重复计算,是本题的最优解。
- 这种“一次递归返回多个值”的技巧在树形 DP 中非常常见,例如求二叉树的最大路径和、二叉树的直径等问题。
- 也可以使用迭代后序遍历(栈 + 状态标记)实现,但递归代码更简洁易读。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 笺札!






