LCA 最近公共祖先 問題的新老解法對比

2021-06-19 11:12:04 字數 1374 閱讀 8257

lca(least common ancestors)問題描述:找出給定二叉樹中的兩個指定節點的最近公共祖先。

本文給出兩種方法,一種是網上看到的,**很簡潔,另外一種是我自己優化過的,思路上更簡單易懂。

第一種:

node *lca(node *root, node *p, node *q)
**非常簡潔,基本思路就是在當前node的left和right中尋找目標node,如果找到就返回,沒找到就返回null。

如果目標node分布在left和right,由於這個迭代演算法是自底向上的,所以當前node就是最近公共祖先,否則的話必然l,r中有乙個為null,另外乙個不是null,此時返回非null的即可,說得比較繞,慢慢回想就能理解。

第二種,自己的方法:

private static int targetx=0;

private static int targety=0;

private static hashtabler= new hashtable();

public static node findlca(node root,string x,string y,int index)

if(root.data.equals(y))

r.put(index, root);

findlca(root.left,x,y,index*2);

findlca(root.right,x,y,index*2+1);

} if(index == 1)

else

} return r.get(targetx);

} else

}

主要思路就是給每乙個結點賦乙個下標,對於下標為index的node的left和right,下標分別為index*2,index*2+1。這樣就可以給每乙個結點乙個下標,也只需要遍歷一遍樹即可完成任務。舉例說明:對於結構如下的二叉樹

我的演算法預設根節點下標為1,通過我的演算法得到a,b,c,d,e,f的下標為:1,2,3,6,7,12

而知道了下標計算 公共祖先就非常簡單,將兩個目標節點的下標中大的那個不斷除以2,直到相等為止。思路非常明確,通過下標的倍數關係將結點的父子關係反應出來。簡單易懂。例如要求b和d的lca,就取出下標2和6,d的父結點c的下標為:6/2=3,3依然大於b的下標2,所以繼續找c的父節點的下標:3/2=1,此時2/2=1,所以他們的lca就是下標為1的結點a!

除以2的過程相當於將當前節點到根節點所經過的結點全部找到了,如果將兩個目標結點的這個結點序列標記為l1和l2,那麼我的**的後半部分就是在找l1和l2的第乙個交叉結點。

最近公共祖先 LCA 最近公共祖先

直接暴力搜尋參考 普通搜尋每次查詢都需要 樸素演算法是一層一層往上找,倍增的話直接預處理出乙個 具體做法是 維護乙個 的關係來線性求出這個陣列 int anc n 31 int dep n 記錄節點深度 void dfs int u,int parent for int i 0 i g u size...

最近公共祖先 最近公共祖先(LCA)

如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。輸入格式 第一行包含三個正整數n m s,分別表示樹的結點個數 詢問的個數和樹根結點的序號。接下來n 1行每行包含兩個正整數x y,表示x結點和y結點之間有一條直接連線的邊 資料保證可以構成樹 接下來m行每行包含兩個正整數a b,表示詢問...

最近公共祖先問題(LCA)

最近公共祖先問題 lca 下面的內容來自演算法藝術與資訊學競賽一書 lca問題 給出乙個有根樹t,對於任意兩個節點u和v,求出 lca t,u,v 即離根最遠的結點x,使得x同時是u和v的祖先。從上面的遞推方法,給我們乙個啟示。當l u l v 時,可以根據lca u,v 的答案把所有結點分成若干個...