第一行输入两个整数 n 和 root,n 表示二叉树的总节点个数,root 表示二叉树的根节点。
以下 n 行每行三个整数 fa,lch,rch,表示 fa 的左儿子为 lch,右儿子为 rch。(如果 lch 为 0 则表示 fa 没有左儿子,rch同理)
最后一行为节点 o1 和 o2。
输出一个整数表示答案。
8 1 1 2 3 2 4 5 4 0 0 5 0 0 3 6 7 6 0 0 7 8 0 8 0 0 4 5
2
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Queue;
import java.util.LinkedList;
class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 构建二叉树
String[] params = br.readLine().split(" ");
int n = Integer.parseInt(params[0]);
TreeNode root = new TreeNode(Integer.parseInt(params[1]));
HashMap<Integer, TreeNode> map = new HashMap<>();
map.put(root.val, root);
for(int i = 0; i < n; i++){
params = br.readLine().split(" ");
int val = Integer.parseInt(params[0]);
int leftVal = Integer.parseInt(params[1]);
int rightVal = Integer.parseInt(params[2]);
TreeNode node = map.get(val);
if(leftVal != 0) {
node.left = new TreeNode(leftVal);
map.put(leftVal, node.left);
}
if(rightVal != 0) {
node.right = new TreeNode(rightVal);
map.put(rightVal, node.right);
}
}
// 获得最近公共祖先
params = br.readLine().split(" ");
TreeNode p = map.get(Integer.parseInt(params[0])), q = map.get(Integer.parseInt(params[1]));
System.out.println(lowestCommonAncestor(root, p, q).val);
}
private static TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
HashMap<TreeNode, TreeNode> child2parent = new HashMap<>();
child2parent.put(root, root); // 根的父节点是自己
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
TreeNode node = queue.poll();
if(node.left != null){
queue.offer(node.left);
child2parent.put(node.left, node);
}
if(node.right != null){
queue.offer(node.right);
child2parent.put(node.right, node);
}
}
if(child2parent.get(p) == child2parent.get(q)) return child2parent.get(p);
// 先记录p往上的路径
HashSet<TreeNode> memory = new HashSet<>();
memory.add(p);
while(child2parent.get(p) != p){
memory.add(child2parent.get(p));
p = child2parent.get(p);
}
// 然后再从q往上找最先与路径相交的节点
while(!memory.contains(q)) q = child2parent.get(q);
return q;
}
} import java.util.*;
public class Main {
static HashMap<Integer, Integer[]> hm;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] str = sc.nextLine().split(" ");
int n = Integer.parseInt(str[0]);
int r = Integer.parseInt(str[1]);
Integer[] child;
hm = new HashMap<>();
for(int i = 0;i < n;i++){
String[] str1 = sc.nextLine().split(" ");
int fa = Integer.parseInt(str1[0]);
int lc = Integer.parseInt(str1[1]);
int rc = Integer.parseInt(str1[2]);
child = new Integer[2];
child[0] = lc;
child[1] = rc;
hm.put(fa, child);
}
String[] str2 = sc.nextLine().split(" ");
int o1 = Integer.parseInt(str2[0]);
int o2 = Integer.parseInt(str2[1]);
Node root = new Node(r);
Node node1 = new Node(o1);
Node node2 = new Node(o2);
buildTree(root);
Node res = LCA(root, node1, node2);
System.out.println(res.val);
}
// 递归查找最近公共祖先
private static Node LCA(Node root, Node node1, Node node2){
if(root == null){
return null;
}
if(root.val == node1.val){
return node1;
}
if(root.val == node2.val){
return node2;
}
Node left = LCA(root.left, node1,node2);
Node right = LCA(root.right, node1,node2);
if(left != null && right != null){
return root;
}else if(left == null){
return right;
}else{
return left;
}
}
private static void buildTree(Node root) {
if(root == null)
return;
if(hm.containsKey(root.val)){
Node lc = null;
Node rc =null;
Integer[] ch = hm.get(root.val);
if(ch[0]!= 0){
lc = new Node(ch[0]);
lc.parent = root;
}
if(ch[1]!= 0){
rc = new Node(ch[1]);
rc.parent = root;
}
root.left = lc;
root.right = rc;
buildTree(lc);
buildTree(rc);
}
}
}
class Node {
int val;
Node parent;
Node left;
Node right;
public Node(int val){
this.val = val;
}
}