ID: 742
TITLE: 二叉树最近的叶节点
TAG: Java
如果我们将树转换为图,则我们可以通过宽度优先搜索找到最近的叶子节点。
算法:
k
的节点进行宽度优先搜索,以便按节点 k
的距离顺序访问每个节点。当遇到叶节点时,则它就是最近的叶节点。class Solution(object):
def findClosestLeaf(self, root, k):
graph = collections.defaultdict(list)
def dfs(node, par = None):
if node:
graph[node].append(par)
graph[par].append(node)
dfs(node.left, node)
dfs(node.right, node)
dfs(root)
queue = collections.deque(node for node in graph
if node and node.val == k)
seen = set(queue)
while queue:
node = queue.popleft()
if node:
if len(graph[node]) <= 1:
return node.val
for nei in graph[node]:
if nei not in seen:
seen.add(nei)
queue.append(nei)
class Solution {
public int findClosestLeaf(TreeNode root, int k) {
Map> graph = new HashMap();
dfs(graph, root, null);
Queue queue = new LinkedList();
Set seen = new HashSet();
for (TreeNode node: graph.keySet()) {
if (node != null && node.val == k) {
queue.add(node);
seen.add(node);
}
}
while (!queue.isEmpty()) {
TreeNode node = queue.poll();
if (node != null) {
if (graph.get(node).size() <= 1)
return node.val;
for (TreeNode nei: graph.get(node)) {
if (!seen.contains(nei)) {
seen.add(nei);
queue.add(nei);
}
}
}
}
throw null;
}
public void dfs(Map> graph, TreeNode node, TreeNode parent) {
if (node != null) {
if (!graph.containsKey(node)) graph.put(node, new LinkedList());
if (!graph.containsKey(parent)) graph.put(parent, new LinkedList());
graph.get(node).add(parent);
graph.get(parent).add(node);
dfs(graph, node.left, node);
dfs(graph, node.right, node);
}
}
}
复杂度分析
算法:
target
有一个最低的公共祖先,而且在从 root
到 target
的路径上。我们可以用任何有效的遍历方式找到从 root
到 target
的路径,并查看路径上每个节点的注释,以确定所有候选叶节点,选择最佳的一个。class Solution(object):
def findClosestLeaf(self, root, k):
annotation = {}
def closest_leaf(root):
if root not in annotation:
if not root:
ans = float('inf'), None
elif not root.left and not root.right:
ans = 0, root
else:
d1, leaf1 = closest_leaf(root.left)
d2, leaf2 = closest_leaf(root.right)
ans = min(d1, d2) + 1, leaf1 if d1 < d2 else leaf2
annotation[root] = ans
return annotation[root]
#Search for node.val == k
path = []
def dfs(node):
if not node:
return
if node.val == k:
path.append(node)
return True
path.append(node)
ans1 = dfs(node.left)
if ans1: return True
ans2 = dfs(node.right)
if ans2: return True
path.pop()
dfs(root)
dist, leaf = float('inf'), None
for i, node in enumerate(path):
d0, leaf0 = closest_leaf(node)
d0 += len(path) - 1 - i
if d0 < dist:
dist = d0
leaf = leaf0
return leaf.val
class Solution {
List path;
Map annotation;
public int findClosestLeaf(TreeNode root, int k) {
path = new ArrayList();
annotation = new HashMap();
dfs(root, k);
int distanceFromTarget = path.size() - 1;
int dist = Integer.MAX_VALUE;
TreeNode leaf = null;
for (TreeNode node: path) {
LeafResult lr = closestLeaf(node);
if (lr.dist + distanceFromTarget < dist) {
dist = lr.dist + distanceFromTarget;
leaf = lr.node;
}
distanceFromTarget--;
}
return leaf.val;
}
public boolean dfs(TreeNode node, int k) {
if (node == null) {
return false;
} else if (node.val == k) {
path.add(node);
return true;
} else {
path.add(node);
boolean ans = dfs(node.left, k);
if (ans) return true;
ans = dfs(node.right, k);
if (ans) return true;
path.remove(path.size() - 1);
return false;
}
}
public LeafResult closestLeaf(TreeNode root) {
if (root == null) {
return new LeafResult(null, Integer.MAX_VALUE);
} else if (root.left == null && root.right == null) {
return new LeafResult(root, 0);
} else if (annotation.containsKey(root)) {
return annotation.get(root);
} else {
LeafResult r1 = closestLeaf(root.left);
LeafResult r2 = closestLeaf(root.right);
LeafResult ans = new LeafResult(r1.dist < r2.dist ? r1.node : r2.node,
Math.min(r1.dist, r2.dist) + 1);
annotation.put(root, ans);
return ans;
}
}
}
class LeafResult {
TreeNode node;
int dist;
LeafResult(TreeNode n, int d) {
node = n;
dist = d;
}
}
复杂度分析