在二叉樹中找到兩個節點的最近公共祖先(高階)
給定一棵二叉樹,多次給出這棵樹上的兩個節點 o1 和 o2,請對於每次詢問,找到 o1 和 o2 的最近公共祖先節點。
輸入描述:
第一行輸入兩個整數 n 和 root,n 表示二叉樹的總節點個數,root 表示二叉樹的根節點。
以下 n 行每行三個整數 fa,lch,rch,表示 fa 的左兒子為 lch,右兒子為 rch。(如果 lch 為 0 則表示 fa 沒有左兒子,rch同理)
第 n+2 行輸入乙個整數 m,表示詢問的次數。
以下 m 行每行兩個節點 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
44 5
5 26 8
5 8
輸出223
1
備註:
1 ≤n
≤1000
1 \leq n \leq 1000
1≤n≤10
00 1≤m
≤106
1 \leq m \leq 10^6
1≤m≤1061≤
fa,l
ch,r
ch,r
oot,
o1,o
2≤
n1 \leq fa,lch,rch,root,o_1,o_2 \leq n
1≤fa,l
ch,r
ch,r
oot,
o1,
o2≤
n o 1≠
o2
o_1 \neq o_2
o1=
o2題解:
建樹過程中儲存節點的父節點,每次查詢時,分別儲存每個節點到根節點的序列,最後從尾到首同時遍歷兩個序列,最後乙個相等的節點就是它們的最近公共祖先節點;
離線(提前處理所有節點對的最近公共祖先,查詢時直接返回結果就行):
處理比較麻煩,可參考書上該部分內容。。。
**:
#include
using
namespace std;
const
int n =
1010
;struct bst bst[n]
;int n, rt;
int fa, lch, rch;
int m, o1, o2;
int preo1[n]
, preo2[n]
;int n_o1, n_o2;
void
get_par
(int
&root,
int arr,
int& k)
}int
lca(
int&o1,
int&o2)
if(i <0)
return preo1[i +1]
;else
return preo2[j +1]
;}intmain
(void
)scanf
("%d"
,&m)
;while
(m--
)return0;
}
在二叉樹中找到兩個節點的最近公共祖先 I
給定一棵二叉樹的頭節點 head,以及這棵樹中的兩個節點 o1 和 o2,請返回 o1 和 o2 的最 近公共祖先節點。說明 o1和o2要麼同時都在二叉樹上,要麼同時都不在二叉樹上。後序遍歷二叉樹,假設遍歷到的當前節點為 cur。因為是後序遍歷,所以 先處理 cur 的兩棵子樹。假設處理 cur 左...
在二叉樹中找到兩個節點的最近公共祖先 再高階
在二叉樹中找到兩個節點的最近公共祖先 再高階 給定一棵二叉樹,多次給出這棵樹上的兩個節點 o1 和 o2,請對於每次詢問,找到 o1 和 o2 的最近公共祖先節點。輸入描述 第一行輸入兩個整數 n 和 root,n 表示二叉樹的總節點個數,root 表示二叉樹的根節點。以下 n 行每行三個整數 fa...
演算法實現 在二叉樹中找到兩個節點的最近公共祖先
該題目來自一次面試。在二叉樹中找到兩個節點的最近公共祖先 高階 給定一棵二叉樹,多次給出這棵樹上的兩個節點 o1 和 o2,請對於每次詢問,找到 o1 和 o2 的最近公共祖先節點。輸入描述 第一行輸入兩個整數 n 和 root,n 表示二叉樹的總節點個數,root 表示二叉樹的根節點。以下 n 行...