本文正在参与掘金团队号上线活动,点击 查看大厂春招职位
一、题目描述:
今天给大家分享的题目是二叉树的坡度。和之前分享过的一篇文章有着异曲同工之妙。
题目要求得是整个二叉树的坡度,即树中所有节点的坡度之和。而一个节点的坡度定义是这个节点的左右子树节点和的差的绝对值。空节点的坡度都是0。
二、思路分析:
遇到树的题目,直接递归返回就完事了。
递归
-
我们还是从最底层的叶子节点开始往上考虑,考虑每个节点能够提供给父节点的收益是什么,有多少。这里我们定义每个节点返回给其父亲节点的收益是其子树的元素和。
-
对于每个叶子节点,因为其左右孩子都是NULL,相当于左右孩子给她的收益是0,所以递归的返回是root == null时返回0。那么叶子节点能提供给父节点的收益就是叶子节点本身的值+0。递归函数里返回的是当前子树的所有元素和,需要加上root节点本身,即:
root->val + $left + $right;同时需要在遍历到当前子树的时候,记录下来当前节点的坡度,使用全局变量累加即可。 -
时间复杂度:O(N),这里 N 二叉树中节点的个数。
-
空间复杂度:O(H),H是二叉树的高度。
三、AC 代码:
protected $res;
function findTilt($root) {
$this->res = 0;
$this->help($root);
return $this->res;
}
protected function help($root) {
if ($root == null) {
return 0;
}
$left = $this->help($root->left);
$right = $this->help($root->right);
$this->res += abs($left - $right);
return ($left + $right) + $root->val;
}
四、总结:
二叉树的题目,递归即可。递归需要考虑递归的结束条件和递归的返回,返回可以理解为子节点能给父节点提供的收益,一般对照着题目的要求,在纸上简单的画一下,就能得出。本文中子节点提供给父节点的收益即递归的返回是每个子树的所有节点的值的和。因为题目求得是所有节点的坡度之和,所以在遍历的时候使用全局变量记录下来每个节点得到的坡度,最后即为所求。