补充:倍增LCA算法(大跳算法)
O(h)
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.*; class TreeNode{ TreeNode left; TreeNode right; int val; public TreeNode(int val) { this.val = val; left = null; right = null; } } public class Main { public static Scanner sc = new Scanner(System.in); public static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); public static long mod = (long) Math.pow(2, 29); public static void main(String[] args) throws Exception { String line; String[] strArr; line = reader.readLine(); strArr = line.split(" "); int n = Integer.valueOf(strArr[0]); int rootVal = Integer.valueOf(strArr[1]); Map<Integer, TreeNode> mp = new HashMap<>(n); for (int i = 0; i < n; i++) { line = reader.readLine(); strArr = line.split(" "); int val = Integer.valueOf(strArr[0]); int leftVal = Integer.valueOf(strArr[1]); int rightVal = Integer.valueOf(strArr[2]); if (!mp.containsKey(val)) { mp.put(val, new TreeNode(val)); } if (leftVal != 0) { if (!mp.containsKey(leftVal)) { mp.put(leftVal, new TreeNode(leftVal)); } mp.get(val).left = mp.get(leftVal); } if (rightVal != 0) { if (!mp.containsKey(rightVal)) { mp.put(rightVal, new TreeNode(rightVal)); } mp.get(val).right = mp.get(rightVal); } } line = reader.readLine(); strArr = line.split(" "); int p = Integer.valueOf(strArr[0]); int q = Integer.valueOf(strArr[1]); TreeNode root = mp.get(rootVal); System.out.println(findNode(root, p, q)); } // static int findNode(TreeNode root, int p, int q){ List<Integer> path = new ArrayList<>(); dfs(root,path, p, q); int ans = firstSame(path1, path2); return ans; } static int firstSame( List<Integer> l1, List<Integer> l2){ int size1 = l1.size(); int size2 = l2.size(); int i = 0; int j = 0; while (i < size1 && j < size2 && l1.get(i).equals(l2.get(j))){ i ++; j ++; } return l1.get(i - 1); } static void dfs(TreeNode root, List<Integer> path, int p, int q){ if(root == null){ return; } if(root.val == p){ for(Integer i: path){ path1.add(i); } path1.add(p); } if(root.val == q){ for(Integer i: path){ path2.add(i); } path2.add(q); } path.add(root.val); int size = path.size(); dfs(root.left, path, p ,q); dfs(root.right, path, p ,q); path.remove(size-1); } static List<Integer> path1 = new ArrayList<>(); static List<Integer> path2 = new ArrayList<>(); } /* 6 / \ 3 9 / \ / \ 1 4 8 10 \ \ / 2 5 7 10 6 6 3 9 3 1 4 1 0 2 2 0 0 4 0 5 5 0 0 9 8 10 10 0 0 8 7 0 7 0 0 7 5 3 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.util.*; class TreeNode{ TreeNode left; TreeNode right; int val; public TreeNode(int val) { this.val = val; left = null; right = null; } } public class Main { public static Scanner sc = new Scanner(System.in); public static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); public static long mod = (long) Math.pow(2, 29); public static void main(String[] args) throws Exception { String line; String[] strArr; line = reader.readLine(); strArr = line.split(" "); int n = Integer.valueOf(strArr[0]); int rootVal = Integer.valueOf(strArr[1]); Map<Integer, TreeNode> mp = new HashMap<>(n); for (int i = 0; i < n; i++) { line = reader.readLine(); strArr = line.split(" "); int val = Integer.valueOf(strArr[0]); int leftVal = Integer.valueOf(strArr[1]); int rightVal = Integer.valueOf(strArr[2]); if (!mp.containsKey(val)) { mp.put(val, new TreeNode(val)); } if (leftVal != 0) { if (!mp.containsKey(leftVal)) { mp.put(leftVal, new TreeNode(leftVal)); } mp.get(val).left = mp.get(leftVal); } if (rightVal != 0) { if (!mp.containsKey(rightVal)) { mp.put(rightVal, new TreeNode(rightVal)); } mp.get(val).right = mp.get(rightVal); } } line = reader.readLine(); strArr = line.split(" "); int p = Integer.valueOf(strArr[0]); int q = Integer.valueOf(strArr[1]); TreeNode ancestor = findAncestorNode(mp.get(rootVal), mp.get(p), mp.get(q)); System.out.println(ancestor == null? 0 : ancestor.val); } // static TreeNode findAncestorNode(TreeNode root, TreeNode p, TreeNode q){ if(root == null){ return null; } if(root.val == p.val || root.val == q.val){ return root; } TreeNode ancestor1 = findAncestorNode(root.left, p, q); TreeNode ancestor2 = findAncestorNode(root.right, p, q); // 要么是root, 要么是root左边的某个节点,要么是右边的节点 if(ancestor1 == null && ancestor2 != null){ return ancestor2; } if(ancestor1 != null && ancestor2 == null){ return ancestor1; } if(ancestor1 != null && ancestor2 != null && ancestor1 == ancestor2){ return ancestor1; } if(ancestor1 == null && ancestor2 == null){ return null; } return root; } } /* 6 / \ 3 9 / \ / \ 1 4 8 10 \ \ / 2 5 7 10 6 6 3 9 3 1 4 1 0 2 2 0 0 4 0 5 5 0 0 9 8 10 10 0 0 8 7 0 7 0 0 4 5 4 1 / \ 2 3 / \ / \ 4 5 6 7 / 8 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 */