樹的最近公共祖先

2021-10-03 23:40:21 字數 2775 閱讀 5505

做了一些二叉樹的題,發現二叉樹的查詢問題一般都是從左右子樹遞迴去解決,也往往都能得到答案,因此,這道題可以考慮是否能從左右子樹進行遞迴去解決呢?

首先,要想通過遞迴來實現,就需要先確定臨界條件,那麼臨界條件是什麼呢?換句話說,臨界條件就是遞迴中能夠直接返回的特殊情況,第一點則是最常見的「判空」,判斷根結點是否是空節點,如果是,那麼肯定就可以馬上返回了,這是乙個臨界條件;再來考慮題意,在以root為根結點的樹中找到p結點和q結點的最近公共祖先,那麼特殊情況是什麼呢?很顯然,特殊情況就是根結點就等於q結點或p結點的情況,想一下,如果根結點為二者之一,那麼根結點就必定是最近公共祖先了,這時直接返回root即可。由此看來,這道題就一共有三種特殊情況,root == q 、root == p和root==null,這三種情況均直接返回root即可。

根據臨界條件,實際上可以發現這道題已經被簡化為查詢以root為根結點的樹上是否有p結點或者q結點,如果有就返回p結點或q結點,否則返回null。

這樣一來其實就很簡單了,從左右子樹分別進行遞迴,即查詢左右子樹上是否有p結點或者q結點,就一共有4種情況:

第一種情況:左子樹和右子樹均找沒有p結點或者q結點;(這裡特別需要注意,雖然題目上說了p結點和q結點必定都存在,但是遞迴的時候必須把所有情況都考慮進去,因為題目給的條件是針對於整棵樹,而遞迴會到區域性,不一定都滿足整體條件)

第二種情況:左子樹上能找到,但是右子樹上找不到,此時就應當直接返回左子樹的查詢結果;

第三種情況:右子樹上能找到,但是左子樹上找不到,此時就應當直接返回右子樹的查詢結果;

第四種情況:左右子樹上均能找到,說明此時的p結點和q結點分居root結點兩側,此時就應當直接返回root結點了。

treenode*

lowestcommonancestor

(treenode* root, treenode* p, treenode* q)

/**

* definition for a binary tree node.

* struct treenode //建構函式,對二叉樹進行初始化

* };

*/#if 0

//遞迴

class

solution};

#elif 1

//迭代

class

solution

return root;}}

;#endif

/**

* definition for a binary tree node.

* struct treenode

* };

*/class

solution

//查詢根節點到目標節點的路徑(先序遍歷,dfs)

bool

getnodepath

(treenode* root, treenode* pnode, vector

>

& path)

//從兩個路徑中尋找第乙個公共節點

treenode*

getcommonnode

(vector

>

& path1,vector

>

& path2)

return plast;

//沒有公共節點,則返回空指標}}

;

//從兩個路徑中尋找第乙個公共節點

treenode*

getcommonnode

(vector

>

& path1,vector

>

& path2)

return

nullptr

;//沒有公共節點,則返回空指標

此時3為5和4的公共祖先,但不是最近公共祖先。

// 題目:輸入兩個樹(普通樹)結點,求它們的最低公共祖先。

#include

#include

"..\utilities\tree.h"

#include

using

namespace std;

/*struct treenode;

*/bool

getnodepath

(const treenode* proot,

const treenode* pnode, list<

const treenode*

>

& path)if(

!found)

path.

pop_back()

;return found;

}const treenode* getlastcommonnode

(const list<

const treenode*

>

& path1,

const list<

const treenode*

>

& path2

)return plast;

}const treenode*

getlastcommonparent

(const treenode* proot,

const treenode* pnode1,

const treenode* pnode2)

最近公共祖先 python 最近公共祖先

lca演算法樸素演算法 也就是我們所說的暴力演算法,大致的思路是從樹根開始,往下迭代,如果當前結點比兩個結點都小,那麼說明要從樹的右子樹中找 相反則從左子樹中查詢 直到找到乙個結點在當前結點的左邊,乙個在右邊,說明當前結點為最近公共祖先,如果乙個結點是另外乙個結點的祖先,那麼返回前面結點的父親結點即...

最近公共祖先 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,表示詢問...