二元樹的最近共同祖先 | Medium | LeetCode#236. Lowest Common Ancestor of a Binary Tree
題目敘述
- 題目難度:
Medium
- 題目敘述: 給定一個 binary tree,請找到任兩節點
p
和q
的 lowest common ancestor (LCA)
最近公同祖先(lowest common ancestor): 是指在節點 p
和 q
之間,二元樹 T
中最低的、同時擁有 p
和 q
作為後代的節點 (本題允許當前節點是自己的後代)
解法
一開始的想法
想法一樣會是 DFS,因為在正常實踐 DFS 的過程中,我們是透過遞迴函式呼叫來實現,Ancestor 一定會是 descendant 的 caller之一。因此朝著 DFS方向去想。另外沒必要把 Traversal全部跑完,只要能夠找到 p
與 q
即可。
我的解法
1 | /** |
在這個 lowestCommonAncestor
函數內,終止條件會是,一旦碰到 leaf 就返回,或者找到 p
或 q
節點就回傳節點。 接下來就是 dfs 遞迴呼叫,本題使用 post-order traversal,因為要找的是 Ancestor,因此 每個子樹的root節點會最後才造訪,另外在左右child 的遞迴結果會分別保存在 *left
和 *right
指標中。而造訪節點要做的事就是做判斷,如果 left
與 right
都不為空,就代表已經找到 p
跟 q
,因此當前節點會是他們的共同祖先。
而如果 left
與 right
其中一個還沒找到,那就將當前的 left
或 right
繼續回傳給 Caller。
最後一行的
nullptr
主要是因為 leetcode 在 run 的時候如果函數有 return value,那他會期待每個控制路徑都要有 return 否則不給過。其實可以將 return 那邊改寫成下面這樣,就比較短。
1 | if (left != nullptr && right != nullptr) return root; |
執行結果
更好的作法
我看解答區有人用4行就寫出來了,但邏輯跟上面一樣,只是寫得更加精簡
1 | TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { |
複雜度
時間複雜度
$O(N)$
空間複雜度
Worst Case: $O(N)$
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Kevin Liu's 部落格 || Technical || Travel!
評論