题目
给你一棵根为 root 的二叉树,请你返回二叉树中好节点的数目。
「好节点」X 定义为:从根到该节点 X 所经过的节点中,没有任何节点的值大于 X 的值。

解析
我的思路:
// 从根开始深度遍历每个节点,计数器初始值为0
// 记录从根到当前节点经过路径中的最大值
// 如果最大值都不超过当前节点的值,则计数器加1
-
count是外部变量,在闭包中被所有递归调用共享 -
每次遇到 good node 时直接修改外部变量
count++ -
递归函数没有返回值,只是通过副作用修改外部状态
灵神思路(官方题解也是):
递归递归,先「递」后「归」。
我们可以在向下递归的同时,额外维护一个参数 mx 表示从根节点到当前节点之前,路径上的最大节点值。
- 如果当前节点为空,到达递归边界,返回 0。
- 递归左子树 goodNodes(root.left, max(mx, root.val)),获取左子树的好节点个数 left。
- 递归右子树 goodNodes(root.right, max(mx, root.val)),获取右子树的好节点个数 right。
- 如果当前节点是好节点,即 mx <= root.val,那么返回 left+right+1。否则返回 left+right。
作者:灵茶山艾府
链接:https://leetcode.cn/problems/count-good-nodes-in-binary-tree/solutions/2403677/jian-ji-xie-fa-pythonjavacgojs-by-endles-gwxt/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
答案
我的写法:只有"递",没有"归"
递:在向下递归的过程中,通过外部变量
count直接记录结果没有归:递归函数没有返回值,不通过返回值向上传递信息
答案写法:完整的"递"和"归"
递:向下传递 路径上的最大节点值 信息
归:向上返回子树的结果进行累加
我的答案(这种写法属于带信息“递”,但是没有“归”)
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var goodNodes = function(root) {
// 从根开始深度遍历每个节点,计数器初始值为0
// 记录从根到当前节点经过路径中的最大值
// 如果最大值都不超过当前节点的值,则计数器加1
if(root === null) return 0;
let count = 0;
function dfs(node, maxVal) {
if(node === null) return;
if(maxVal <= node.val) {
count++;
maxVal = node.val;
}
dfs(node.left, maxVal);
dfs(node.right, maxVal);
}
dfs(root, -Infinity);
return count;
};
根据官方题解思路写的答案
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var goodNodes = function(root) {
// 对于每个节点:
// 当前节点的count = 当前节点自身是否是good node(0或1)
// + 左子树的good nodes数量
// + 右子树的good nodes数量
if(root === null) return 0;
function dfs(node, maxVal) {
if(node === null) return 0;
let count = 0;
if(maxVal <= node.val) {
count++;
maxVal = node.val;
}
count += dfs(node.left, maxVal) + dfs(node.right, maxVal);
return count;
}
return dfs(root, -Infinity);
};
灵神答案
var goodNodes = function (root, mx = -Infinity) {
if (root === null)
return 0;
const left = goodNodes(root.left, Math.max(mx, root.val));
const right = goodNodes(root.right, Math.max(mx, root.val));
return left + right + (mx <= root.val);
};
// 作者:灵茶山艾府
// 链接:https://leetcode.cn/problems/count-good-nodes-in-binary-tree/solutions/2403677/jian-ji-xie-fa-pythonjavacgojs-by-endles-gwxt/
// 来源:力扣(LeetCode)
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
复杂度分析
时间复杂度:O(n),其中 n 为二叉树的节点个数。每个节点都会递归恰好一次。
空间复杂度:O(n)。最坏情况下,二叉树是一条链,递归需要 O(n) 的栈空间。作者:灵茶山艾府
链接:https://leetcode.cn/problems/count-good-nodes-in-binary-tree/solutions/2403677/jian-ji-xie-fa-pythonjavacgojs-by-endles-gwxt/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

1255

被折叠的 条评论
为什么被折叠?



