方法1
Convert binary tree to graph, use BFS to find the closest leaf.
Step1: use BFS to go through the tree and store the neighbors of each node (node.left, node.right, parent of node)
Step2: get valid nodes with node.val == k.
Step3: BFS to get the closest leaf of each node, use global variable to update distance and node.
Time complexity: O(n), Space complexity: O(n)
** the leaf and the target node may not in the same side of root, so it’s hard to use divide-and-conquer. For example, [1,2,3,4,null,null,null,5,null,6], k = 2
# use dict to store a node and its neighbor node, make the tree as a undirected graph
class Solution:
def findClosestLeaf(self, root: TreeNode, k: int) -> int:
if not root:
return None
neighbors = defaultdict(list)
neighbors[root] = []
queue = deque([root])
while queue:
node = queue.popleft()
if node.left:
neighbors[node].append(node.left)
neighbors[node.left].append(node)
queue.append(node.left)
if node.right:
neighbors[node].append(node.right)
neighbors[node.right].append(node)
queue.append(node.right)
valid_nodes = []
for node in neighbors.keys():
if node.val == k:
valid_nodes.append(node)
length = float('inf')
res = None
for node in valid_nodes:
l, leaf = self.get_leaf(node, neighbors)
if l < length:
res = leaf
return res.val
def get_leaf(self, root, neighbors):
visited = {}
queue = deque([root])
visited[root] = 0
while queue:
for i in range(len(queue)):
node = queue.popleft()
if not node.left and not node.right:
return visited[node], node
for next_node in neighbors[node]:
if next_node not in visited:
queue.append(next_node)
visited[next_node] = visited[node] + 1```