《劍指offer》樹中兩個結點的最低公共祖先

2021-06-30 16:29:21 字數 2060 閱讀 7365

說實話,和這題很有緣分。首先,這個題目給我印象很深,其次,今天在做蘑菇街實習生筆試時遇到了這個題目,所以感覺應該寫部落格,把這個題目記錄下來。

筆試時遇到的題目是:給定二叉樹中的兩個結點,尋找最低公共節點。

這是一種情況,是比較簡單的情況。

這種情況就相當於求兩條鍊錶的公共節點。求解很簡單,先把遍歷把兩條鍊錶的長度求得。加入list1長a,list2長為b,求則a、b中的較大者先從頭遍歷走a-b步,然後兩條鍊錶同時遍歷,第乙個相同的節點是最低公父節點。

這種情況難點。所謂兩個結點的公共祖先,指的是兩個結點都出現在現在某個節點的子樹中。我們可以從根結點開始遍歷樹,每遍歷到乙個結點時,判斷兩個輸入結點是不是在它的子樹中。如果在子樹中,則分別遍歷它的所有子結點,並判斷兩個輸入結點是不是在它們的子樹中。這樣一直向下找,直到找到乙個結點,它自己的子樹同時包含兩個輸入的子結點而它的子結點卻沒有,那麼該結點就是最低的公共祖先。

我在這次筆試就是採用這種解法。

typedef

struct treenode treenode;

/* 檢視root結點的子樹是否包含distri */

bool hasnode(treenode *root, treenode *distri)

if (root->val == distri->val)

return hasnode(root->left, distri) || hasnode(root->right, distri);

}treenode *commomfather(treenode *root, treenode *node1, treenode *node2)else

if(null != commomfather(root->left, node1, node2))else

if ((null != commomfather(root->left, node1, node2))

return null;

}

當然我並沒有檢驗,這是憑記憶回想自己在考場寫的**。

上一種方法很明顯,我們對同一結點都會重複遍歷很多次,我們尋求一種更快的解法。

《劍指offer》提供了一種思路:

使用輔助記憶體,用兩個鍊錶分別儲存從根結點到輸入兩個結點的路徑,然後把問題轉換為兩個鍊錶的最後公共結點。

這種解法為了得到根結點開始到輸入的兩個結點的兩條路徑,需要兩次遍歷樹,每一次遍歷需要o(n).得到兩條路徑長度最差是o(n),通常情況下兩條路徑長度是o(logn).

/* 獲取root到node的path */

bool getnodepath(treenode *root, treenode *node, list

&path)

path.push_back(root);

bool found = false;

vector

::iterator it = root->m_vchildren.begin();

while (!found && i < root->m_vchildren.end())

if (!found)

return found;

}/* 獲取相同結點 */

treenode *getlastcommonnode(const

list

&path1, const

list

&path2)

iterator1++;

iterator2++;

} return plast;

}treenode *getlastcommonparent(treenode *root, treenode *node1, treenode *node2)

list

path1;

getnodepath(root, node1, path1);

list

path2;

getnodepath(root, node2, path2);

return getlastcommonnode(path1, path2);

}

好了,完

劍指Offer 68 樹中兩個結點的最低公共祖先

給出乙個二叉樹,輸入兩個樹節點,求它們的最低公共祖先。乙個樹節點的祖先節點包括它本身。注意 輸入的二叉樹不為空 輸入的兩個節點一定不為空,且是二叉樹中的節點 解法一,使用遞迴,若兩個樹節點在根節點的左右子樹上,則公共節點為根節點 若兩個樹節點都在某一子樹上,則公共節點在該子樹上。這個方法遞迴都要查詢...

劍指offer 樹中兩個節點的最低公共祖先

與 劍指offer 得到從根節點開始到輸入的兩個結點的兩條,需要遍歷兩次樹,每遍歷一次的時間複雜度是o n 得到的兩條路徑的長度在最差情況時是o n 通常情況下兩條路徑的長度是o logn include include include using namespace std struct tree...

劍指offer 樹中兩個節點的最低公共祖先

對於這個問題不同的條件可以有不同的解法 binarytreenode getlastcommonparent binarytreenode proot,binarytreenode pnode1,binarytreenode pnode2 普通二叉樹,沒有parent指標 非遞迴的解法 1.獲取結點...