1530. Number of Good Leaf Nodes Pairs
Brute Force
周赛时候看到这题,半天也就想到用 LCA
做 brute force 解,但一直TLE。不过 brute force 其实是能写的,需要利用一下题目的这一条说明:
1 <= distance <= 10
distance 有上限,意味着寻找 LCA
的时候就不需要一直往上找了,超过 distance 即可放弃,因此这个过程可以被看作O(1),思路就可以概括为:
遍历树,找到所有叶节点,用
hash map
记录parent关系(用来在后面步骤中向上追溯)遍历所有叶节点,记录所有距离它小于distance的祖先节点,如果有符合条件的pair,则
LCA
必然在这些祖先节点里在还没遍历到的叶节点中搜索,要求:两个节点与
LCA
之和不大于distance
DFS分治
Tree
问题考虑下分治
,确认要从左右子树分别传递过来什么数据(怎么治)。
容易想到的一个是「当前node
到各个叶节点的距离」,但叶节点本身我们并不关心,只关心数量,所以可以直接记录「到当前节点距离为n的叶节点数量」,且利用distance有限这个条件,可以直接用数组来记录。
题目要找的 good leaf node pairs 在这里有个特点是左右子树各自内部的pairs是被确定的,往上传递的过程中不会再改变,新增来的pairs只可能是左子树的leaf 和右子树leaf形成的pair。所以需要往上传递的是当前子树记录的合格pairs数量。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def countPairs(self, root: TreeNode, distance: int) -> int:
res, parents, leaves = 0, dict(), []
def dfs(c, p):
if not c: return
if not c.left and not c.right: leaves.append(c)
parents[c] = p
dfs(c.left, c)
dfs(c.right, c)
dfs(root, None)
def ifGood(possibleLCA, node):
i, n = 0, node
# 寻找距离之和不大于distance的LCA
while i < distance and n:
if n in possibleLCA and possibleLCA[n] + i <= distance:
return 1
# 当前node不是的话,就往上移动一层
i += 1
n = parents[n]
return 0
for i in range(len(leaves)):
k, l = 0, leaves[i]
ancestors = collections.defaultdict(int)
# 记录当前距离当前叶节点小于distance的所有祖先节点
while k < distance and l:
ancestors[l] = k
l = parents[l]
k += 1
# 在其他叶子节点里,找符合条件的叶节点(两个节点与LCA距离之和不大于distance的)
for j in range(i+1, len(leaves)):
res += ifGood(ancestors, leaves[j])
return res
Last updated
Was this helpful?