1448、统计二叉树中好节点的数目
给你一棵根为 root
的二叉树,请你返回二叉树中好节点的数目。
「好节点」X 定义为:从根到该节点 X 所经过的节点中,没有任何节点的值大于 X 的值。
示例1:
输入:root = [3,1,4,3,null,1,5]
输出:4
示例2:
输入:root = [3,3,null,4,2]
输出:3
示例3:
输入:root = [1]
输出:1
思路:
从根节点到当前节点,没有任何节点的值大于当前节点的值,只需要在递归的时候传递根节点到当前节点的最大值即可,使用先序遍历是因为最大值是从最大值开始计算出来的。
class Solution:
def goodNodes(self, root: TreeNode) -> int:
self.ans = 0
def dfs(root, maxValue=float("-inf")):
if not root: return
# 如果当前节点的值大于最大值,那么结果+1
if root.val >= maxValue:
self.ans += 1
# 更新最大值,并递归左右节点
maxValue = max(maxValue, root.val)
dfs(root.left, maxValue)
dfs(root.right, maxValue)
dfs(root)
return self.ans
1530、好叶子节点对的数量
给你二叉树的根节点 root 和一个整数 distance 。
如果二叉树中两个 叶 节点之间的 最短路径长度 小于或者等于 distance ,那它们就可以构成一组 好叶子节点对 。
返回树中 好叶子节点对的数量 。
示例1:
输入:root = [1,2,3,null,4], distance = 3
输出:1
示例2:
输入:root = [1,2,3,4,5,6,7], distance = 3
输出:2
示例3:
输入:root = [7,1,4,6,null,5,3,null,null,null,null,null,2], distance = 3
输出:1
示例4:
输入:root = [100], distance = 1
输出:0
示例5:
输入:root = [1,1,1], distance = 2
输出:1
思路:
根据题目定义,好叶子对是叶节点的最短距离小于等于distance,而两个叶子节点的最短距离应该等于两个叶子节点相对于最近的祖先的深度之和,而且根据定义,那么好叶子节点对肯定是某个祖先的左右子树的叶子节点,所以可以计算出左右子树的叶子节点的深度,那么相对于该祖先节点来说,那么好叶子节点数量应该左右叶子节点可能深度的笛卡尔积。
class Solution:
def countPairs(self, root: TreeNode, distance: int) -> int:
self.ans = 0
# 递归遍历得到每个根节点各个深度的叶子节点数
def dfs(root, distance):
# 如果没有根节点,直接返回
if not root: return {}
# 如果是叶子节点,说明该节点相对于根(自己)的深度为1,这里返回深度为0的叶子节点树1
if not root.left and not root.right:
return {0: 1}
# 递归得出左右叶子节点深度与叶子节点数目的关系
leftLeaf = dfs(root.left, distance)
rightLeaf = dfs(root.right, distance)
# 遍历左右子树,将可能满足的情况累加到结果中
for i in range(distance + 1):
for j in range(distance -i -1):
self.ans += leftLeaf.get(i, 0) * rightLeaf.get(j, 0)
# 当前层的叶子节点深度与数目的关系,应该是左右叶子节点的深度加一
leafCounts = defaultdict(int)
for i in range(distance):
leafCounts[i+1] += leftLeaf.get(i, 0)
leafCounts[i+1] += rightLeaf.get(i, 0)
return leafCounts
dfs(root, distance)
return self.ans