第一行输入两个整数 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; } }
#include <stdio.h> #include <stdlib.h> typedef int Id; typedef struct { Id id; Id l_child, r_child; } TNodeInfo, *INFO; int lowestCommonAncestor(INFO infos, Id root_id, Id p, Id q) { if (!root_id || root_id == p || root_id == q) return root_id; const int ls = lowestCommonAncestor(infos, (*(infos + root_id)).l_child, p, q); const int rs = lowestCommonAncestor(infos, (*(infos + root_id)).r_child, p, q); return ls && rs ? root_id : ls ? ls : rs; } int main(const int argc, const char** const argv) { int n, root_id; fscanf(stdin, "%d %d", &n, &root_id); TNodeInfo infos[n + 1]; Id fa, l_ch, r_ch; while (n--) { fscanf(stdin, "%d %d %d", &fa, &l_ch, &r_ch); (*(infos + fa)).id = fa; (*(infos + fa)).l_child = l_ch; (*(infos + fa)).r_child = r_ch; } Id o1, o2; fscanf(stdin, "%d %d", &o1, &o2); fprintf(stdout, "%d", lowestCommonAncestor(infos, root_id, o1, o2)); return 0; }
#include <bits/stdc++.h> using namespace std; struct TreeNode{ int val; TreeNode* lch; TreeNode* rch; TreeNode(int x):val(x),lch(NULL),rch(NULL){} }; void createTree(TreeNode* root, int& cnt){ if(cnt == 0) return; int p, l, r; cin >> p >> l >> r; if(l){ TreeNode* lch = new TreeNode(l); root->lch = lch; createTree(root->lch, --cnt); } if(r){ TreeNode* rch = new TreeNode(r); root->rch = rch; createTree(root->rch, --cnt); } return; } TreeNode* findCommonNode(TreeNode* root, int v1, int v2){ if(!root) return NULL; if(root->val == v1 || root->val == v2) return root; TreeNode* left = findCommonNode(root->lch, v1, v2); TreeNode* right = findCommonNode(root->rch, v1, v2); if(left && right) return root; else if(left) return left; else return right; } int main(){ int n, root_val; cin >> n >> root_val; TreeNode* root = new TreeNode(root_val); createTree(root, n); int o1_val, o2_val; cin >> o1_val >> o2_val; TreeNode* node = findCommonNode(root, o1_val, o2_val); cout << node->val << endl; return 0; }
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; } }
// // Created by yuanhao on 2019-8-30. // #include <iostream> using namespace std; //题目描述 //给定一棵二叉树以及这棵树上的两个节点 o1 和 o2,请找到 o1 和 o2 的最近公共祖先节点。 //输入描述: //第一行输入两个整数 n 和 root,n 表示二叉树的总节点个数,root 表示二叉树的根节点。 //以下 n 行每行三个整数 fa,lch,rch,表示 fa 的左儿子为 lch,右儿子为 rch。(如果 lch 为 0 则表示 fa 没有左儿子,rch同理) //最后一行为节点 o1 和 o2。 //输出描述: //输出一个整数表示答案。 // //示例1 //输入 //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 int main() { int n = 0; int root = 0; cin >> n >> root; int father[n + 1]; int f, l, r; for (int i = 0; i < n; i++) { cin >> f >> l >> r; if (l != 0) { father[l] = f; } if (r != 0) { father[r] = f; } } int ln = 0, rn = 0; cin >> ln >> rn; int ld = 0, rd = 0; // 节点深度 l = ln, r = rn; while (l != root) { ld++; l = father[l]; } while (r != root) { rd++; r = father[r]; } l = ln; r = rn; if (ld > rd) { int bd = ld - rd; for (int i = 0; i < bd; i++) { l = father[l]; } } else { int bd = rd - ld; for (int i = 0; i < bd; i++) { r = father[r]; } } while (l != r) { l = father[l]; r = father[r]; } cout << l << endl; // 或者 cout << r << endl; 都是一样的 }
#节点数,根节点 n,root=map(int,input().split()) #树和C1的祖先数组 f,v=[0]*(n+1),[1]*(n+1) #建立树 for _ in range(n): fa,lch,rch=map(int,input().split()) f[lch]=f[rch]=fa c1,c2=map(int,input().split()) #寻找c1的所有祖先 while c1!=root: v[c1],c1=0,f[c1] #第一个没被标记的祖先就是最近公共祖先 while c2!=root and v[c2]: c2=f[c2] print(c2)
class TreeNode: def __init__(self, x): self.val = x self.left = None self.right = None class Solution: def lowestCommonAncestor(self, root: 'TreeNode', p:int, q:int) -> 'TreeNode': if not root&nbs***bsp;root.val == p&nbs***bsp;root.val == q:return root left = self.lowestCommonAncestor(root.left, p, q) right = self.lowestCommonAncestor(root.right, p, q) if left and right: return root if left:return left if right:return right if __name__ == '__main__': n, root_val = map(int, input().split()) node_key = {} lst = [] for i in range(n): v, l, r = map(int, input().split()) lst.append((v ,l, r)) node_key[v] = TreeNode(v) if i == 0:root = node_key[v] for v, l, r in lst: if l: node_key[v].left = node_key[l] if r: node_key[v].right = node_key[r] p, q = map(int, input().split()) node = Solution().lowestCommonAncestor(root, p, q) print(node.val)
import java.util.Scanner; import java.util.HashMap; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int sum = in.nextInt(); int val = in.nextInt(); HashMap<Integer,Node> map = new HashMap<Integer,Node>(); if(sum > 0) { int[][] arr = new int[sum][3]; for(int i = 0; i<sum; i++) { for(int j = 0; j<3; j++){ arr[i][j] = in.nextInt(); } map.put(arr[i][0],new Node(arr[i][0])); } for(int i = 0; i<sum; i++) { if(arr[i][1] != 0) map.get(arr[i][0]).setLeftChild(map.get(arr[i][1])); if(arr[i][2] != 0) map.get(arr[i][0]).setRightChild(map.get(arr[i][2])); } int v1 = in.nextInt(); int v2 = in.nextInt(); Node root = map.get(val); Node child1 = map.get(v1); Node child2 = map.get(v2); System.out.println(new Main().latestCommonAncestor(root,child1,child2).getValue()); } } public Node latestCommonAncestor(Node head, Node child1, Node child2) { if(head == null || head == child1 || head == child2) { return head; } Node left = latestCommonAncestor(head.getLeftChild(),child1,child2); Node right = latestCommonAncestor(head.getRightChild(),child1,child2); if(left != null && right != null) { return head; } return left!=null? left: right; } } class Node { private Node leftC; private Node rightC; private int value; Node(int value) { this.value = value; } public void setLeftChild(Node leftC) { this.leftC = leftC; } public void setRightChild(Node rightC) { this.rightC = rightC; } public Node getLeftChild() { return this.leftC; } public Node getRightChild() { return this.rightC; } public int getValue() { return this.value; } } 运行时间:2253ms 占用内存:241908KB .代码已通过,仅供参考。
import java.util.Scanner; /** * 比较Low的写法,用了boolean数组进行标记 */ public class Main { public static class Node { public int id; public int parent; public int left; public int right; public Node(int id, int left, int right) { this.id = id; this.left = left; this.right = right; } } public static void preOrder(Node[] nodes, int id, int parent) { if (id != 0) { nodes[id].parent = parent; preOrder(nodes, nodes[id].left, id); preOrder(nodes, nodes[id].right, id); } } public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); int root = in.nextInt(); Node[] nodes = new Node[n+1]; boolean[] visited = new boolean[n+1]; for (int i = 0; i < n; i++) { int p = in.nextInt(); int left = in.nextInt(); int right = in.nextInt(); nodes[p] = new Node(p, left, right); } preOrder(nodes, root, 0); int o1 = in.nextInt(), o2 = in.nextInt(); while (o1 != 0) { visited[o1] = true; o1 = nodes[o1].parent; } while (o2 != 0) { if (visited[o2]) { System.out.print(o2); break; } else { o2 = nodes[o2].parent; } } } }
#include <cstdio> (802)#include <queue> using namespace std; int main() { int n, root; priority_queue<int, vector<int>, greater<int>> queue; int dis[n]; scanf("%d %d", &n, &root); int tree[n]; // 使用一维数组保存二叉树,数组的值为对应下标的父节点 for (int i = 1; i <= n; i++) { int left, right, father; scanf("%d %d %d", &father, &left, &right); if (left != 0) { tree[left] = father; } if (right != 0) { tree[right] = father; } } tree[root] = -1; int firstNode, secondNode; scanf("%d %d", &firstNode, &secondNode); int firstCount = -1; // 第一个结点到公共结点的距离 int secondCount = 0; // 第二个结点到公共结点的距离 int firstFatherNodes[n]; // 保存第一个结点的父节点,包括自己 while (firstNode != -1) { firstCount++; firstFatherNodes[firstCount] = firstNode; firstNode = tree[firstNode]; } int secondCurrent = secondNode; for (int i = 0; i <= firstCount; i++) // 计算第二个结点到第一个结点的父结点的距离 { secondCount = 0; secondCurrent = secondNode; while (secondCurrent != firstFatherNodes[i] && secondCurrent != -1) { secondCount++; secondCurrent = tree[secondCurrent]; } if (secondCurrent == -1) { continue; } printf("%d",firstFatherNodes[i]); break; } return 0; }
#include<bits/stdc++.h> using namespace std; int LCA(int root,int* lc,int* rc,int a,int b) { if(!root || root==a || root==b) return root; int l = LCA(lc[root],lc,rc,a,b); int r = LCA(rc[root],lc,rc,a,b); if(!l && !r) return 0; if(l && r) return root; return (l ? l : r); } int main() { int n,root; cin>>n>>root; int p; int* lc = new int[n+1]; int* rc = new int[n+1]; for(int i=0;i<n;++i) { cin>>p; cin>>lc[p]>>rc[p]; } int a,b; cin>>a>>b; cout<<LCA(root,lc,rc,a,b); return 0; }
// father数组+栈 解决 #include <stdio.h> #include <algorithm> #include <stack> #include <cstring> using namespace std; //int matrix[2001][2001]; int f[500001]; int main() { int n, rt; scanf("%d %d", &n, &rt); int fa, lch, rch; memset(f, 0, sizeof(f)); int cnt = n; while(cnt--) { scanf("%d %d %d", &fa, &lch, &rch); if(lch != 0) f[lch] = fa; if(rch != 0) f[rch] = fa; } int o1, o2; scanf("%d %d", &o1, &o2); stack<int>os1; stack<int>os2; os1.push(o1); os2.push(o2); while(f[o1] != 0) { os1.push(f[o1]); o1 = f[o1]; } while(f[o2] != 0 ) { os2.push(f[o2]); o2 = f[o2]; } int ans; int top = os1.top(); while(!os1.empty() && !os2.empty() && top == os2.top()) { ans = top; os1.pop(); os2.pop(); top = os1.top(); } printf("%d\n", ans); return 0; }
#include <iostream> #include <map> using namespace std; map<int, pair<int, int>>in; int a, b; int getparent(int root) { if (root == a || root == b) { return root; } if (root == 0) return 0; int l = getparent(in[root].first); int r = getparent(in[root].second); if (l!=0&&r!=0) { return root; } return l!=0?l:r; } int main() { int m, ro; cin >> m >> ro; int root, left, right; for (int i = 0; i<m; ++i) { cin >> root >> left >> right; in[root] = { left,right }; } cin >> a>>b; cout<<getparent(ro); }
import java.util.*; public class Main{ static HashMap<Integer,Integer[]> hm; static TreeNode rt,o1,o2; public static void main(String[] args) { int n,root; Scanner sc = new Scanner(System.in); n = sc.nextInt(); root = sc.nextInt(); hm = new HashMap<Integer,Integer[]>(); Integer[] t; int val; for(int i=0;i<n;i++) { t = new Integer[2]; val = sc.nextInt(); t[0] = sc.nextInt(); t[1] = sc.nextInt(); hm.put(val,t); } rt = new TreeNode(root); buildTree(rt); //循环构建二叉树 getTreeNodeO1(rt,sc.nextInt()); //前序遍历找到该节点 getTreeNodeO2(rt,sc.nextInt()); //前序遍历找到该节点 //printTree(rt); ArrayList<Integer> al1 = findRtPath(o1); //获得该节点对应的路径 ArrayList<Integer> al2 = findRtPath(o2); //获得该节点对应的路径 ArrayList<Integer[]> commonlst = new ArrayList<Integer[]>(); Integer[] tmp; Integer temp; for(int i=0;i<al1.size();i++){ temp = al1.get(i); if(al2.contains(temp)) { tmp = new Integer[2]; tmp[0] = temp; tmp[1] = i + al2.indexOf(tmp); //路径距离和 commonlst.add(tmp); al2.remove(temp); } } for(int i=0;i<al2.size();i++){ temp = al2.get(i); if(al1.contains(temp)) { tmp = new Integer[2]; tmp[0] = temp; tmp[1] = i + al1.indexOf(tmp); //路径距离和 commonlst.add(tmp); } } Integer near = Integer.MAX_VALUE; //最短路径 Integer res = -1; //结果 for(int i=0;i<commonlst.size();i++) { tmp = commonlst.get(i); if(tmp[1]<near) { res = tmp[0]; near = tmp[1]; } } System.out.println(res); } private static ArrayList<Integer> findRtPath(TreeNode n){ ArrayList<Integer> al = new ArrayList<Integer>(); while(n!=null) { al.add(n.getVal()); n = n.father; } return al; } private static void getTreeNodeO2(TreeNode rt,int n){ assert n>0; if(rt==null) { return; } if(rt.getVal()==n) { o2 = rt; return; } else{ getTreeNodeO2(rt.left,n); getTreeNodeO2(rt.right,n); } } private static void getTreeNodeO1(TreeNode rt,int n){ assert n>0; if(rt==null) { return; } if(rt.getVal()==n) { o1 = rt; return; } else{ getTreeNodeO1(rt.left,n); getTreeNodeO1(rt.right,n); } } private static void printTree(TreeNode rt){ if(rt!=null){ if(rt.getVal()!=0){ System.out.print(rt.getVal()); printTree(rt.left); printTree(rt.right); } } } private static void buildTree(TreeNode rt) { Integer[] t; if(rt!=null && hm.containsKey(rt.getVal())) { t = hm.get(rt.getVal()); TreeNode left,right; left = null; right = null; if(t[0]!=0){ left = new TreeNode(t[0]); left.father = rt; } if(t[1]!=0) { right = new TreeNode(t[1]); right.father = rt; } rt.left = left; rt.right = right; buildTree(left); buildTree(right); } } } class TreeNode{ private int val; public TreeNode left,right,father; public void setVal(int n){ this.val = n; } public int getVal(){ return this.val; } public TreeNode(int n) { this.val = n; left = null; right = null; father = null; } }