742.ツリーの一番近いリーフノード
6422 ワード
ID:742 TITLE:ツリーの一番近いリーフノードTAG:Java
方法一:図に変換する
ツリーを図に変換すると、最も近いリーフノードを幅優先検索で見つけることができます.
アルゴリズム:親ノードから深さ優先探索を行い、各ノードのエッジ に記録する.の後、
複雑度分析時間複雑度:O(N)O(N)O(N).N N Nは二叉木のノード数を指す. 空間複雑度:O(N)O(N)O(N)、図の大きさ.
方法2:
アルゴリズム:は、各ノードから、そのサブツリーの中で最も近いリーフノードがどこにあるかを知っていると仮定する.記憶化された遍歴を使って、これらの情報を記憶することができます. そして、ターゲットに最も近いリーフノードは、
複雑度分析時空複雑度:O(N)O(N)O(N).解析は方法1と同じである.
方法一:図に変換する
ツリーを図に変換すると、最も近いリーフノードを幅優先検索で見つけることができます.
アルゴリズム:
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);
}
}
}
複雑度分析
方法2:
アルゴリズム:
target
と最も低い共通の祖先を有し、root
からtarget
への経路上にあるに違いない.root
からtarget
への経路を任意の有効な遍歴で見つけ、経路上の各ノードの注釈を見て、すべての候補リーフノードを決定し、最適な1つを選択することができます.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;
}
}
複雑度分析