https://blog.csdn.net/qq_36799943/article/details/78250697 這個圖里的子樹講的比較好
https://www.cnblogs.com/zl1991/p/13094997.html 代碼的思路借鑒了一些這篇文章
dfs序的主要作用就是將一個子樹變成序列上的一個連續(xù)區(qū)間。
https://www.zhihu.com/question/46440863/answer/2265938163?utm_id=0
import java.util.*;
class TreeNode {
public int val;
public List<TreeNode> children;
public TreeNode(int val) {
this.val = val;
children = new ArrayList<>();
}
}
class TarjanLCA {
int[] parent; // 并查集的代表元數(shù)組
boolean[] visited; // 是否已訪問
int ans; // 存儲每個單個的LCA
int[] query; // 存儲每個查詢的參數(shù)
public int findLCA(TreeNode root, int[] query) {
// 初始化參數(shù)
this.parent = new int[100];
this.visited = new boolean[100];
this.query = query;
for (int i = 0; i < parent.length; i++) {
parent[i] = i;
}
// 預(yù)處理節(jié)點深度并建圖
dfs(root);
return ans;
}
private void dfs(TreeNode u) {
for (TreeNode child : u.children) {
if (!visited[child.val]) {
dfs(child);
union(u.val, child.val);
visited[child.val] = true;
}
}
if (u.val == query[0] && visited[query[1]]) {
ans = find(query[1]);
return;
} else if (u.val == query[1] && visited[query[0]]) {
ans = find(query[0]);
return;
}
}
private int find(int x) {
if (parent[x] == x) {
return x;
}
return find(parent[x]);
}
// 默認父節(jié)點為x
private void union(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX != rootY) {
parent[rootY] = rootX;
}
}
public static void main(String[] args) {
TreeNode root = new TreeNode(1);
root.children.add(new TreeNode(2));
root.children.add(new TreeNode(3));
root.children.get(0).children.add(new TreeNode(4));
root.children.get(0).children.add(new TreeNode(5));
root.children.get(1).children.add(new TreeNode(6));
root.children.get(1).children.add(new TreeNode(8));
root.children.get(1).children.get(0).children.add(new TreeNode(7));
root.children.get(1).children.get(1).children.add(new TreeNode(9));
int[] query = {7,9};
int ans = new TarjanLCA().findLCA(root, query);
System.out.println(ans);
}
}