持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第 9 天,点击查看活动详情
题目链接
题目描述
给你一个二叉树的根节点 root ,计算并返回 整个树 的坡度 。
一个树的 节点的坡度 定义即为,该节点左子树的节点之和和右子树节点之和的 差的绝对值 。如果没有左子树的话,左子树的节点之和为 0 ;没有右子树的话也是一样。空结点的坡度是 0 。
整个树 的坡度就是其所有节点的坡度之和。
测试用例
示例 1:
输入:root = [4,2,9,3,5,null,7]
输出:15
解释:
节点 3 的坡度:|0-0| = 0(没有子节点)
节点 5 的坡度:|0-0| = 0(没有子节点)
节点 7 的坡度:|0-0| = 0(没有子节点)
节点 2 的坡度:|3-5| = 2(左子树就是左子节点,所以和是 3 ;右子树就是右子节点,所以和是 5 )
节点 9 的坡度:|0-7| = 7(没有左子树,所以和是 0 ;右子树正好是右子节点,所以和是 7 )
节点 4 的坡度:|(3+5+2)-(9+7)| = |10-16| = 6(左子树值为 3、5 和 2 ,和是 10 ;右子树值为 9 和 7 ,和是 16 )
坡度总和:0 + 0 + 0 + 2 + 7 + 6 = 15
限制
- 树中节点的数目在范围 内
题目分析
由题目可知,我们需要求一个节点 node 的左右子树的节点值之和,为 leftSum, rightSum,然后求他们的差值的绝对值为 val = |leftSum - rightSum|,这个 val 就是 node 的坡度
当我们分别计算完每个节点的坡度后,将这些值汇总求和,就是整个数 root 的坡度
涉及到对左右子节点的数据返回,这里需要使用到后续遍历。在最外边定义一个 sum 用于记录数的坡度和。遍历完 node 的左右子节点,我们拿到了 leftSum, rightSum,算出差值追加到 sum。 leftSum + rightSum + node.val 返回给上一级递归,表示 node 为子树根节点的节点值总和。
代码实现
完整的代码实现如下
var findTilt = function (root) {
let sum = 0;
trave(root);
return sum;
function trave(node) {
if (node == null) return 0;
let lv = trave(node.left);
let rv = trave(node.right);
sum += Math.abs(lv - rv);
return lv + rv + node.val;
}
};