【Lintcode】python - [578] Lowest Common Ancestor III 個人解法筆記

題目出處

578 · Lowest Common Ancestor III

難度

medium

個人範例程式碼

"""
Definition of TreeNode:
class TreeNode:
    def __init__(self, val):
        this.val = val
        this.left, this.right = None, None
"""


class Solution:
    """
    @param: root: The root of the binary tree.
    @param: A: A TreeNode
    @param: B: A TreeNode
    @return: Return the LCA of the two nodes.
    """
    def lowestCommonAncestor3(self, root, A, B):
        # write your code here
        self.found_A = False
        self.found_B = False

        ans = self.lca(root, A, B)
        return ans if (self.found_A and self.found_B) else None

    def lca(self, root, A, B):
        if not root:
            return None

        # divide
        found_left = self.lca(root.left, A, B) # keep traverse
        found_right = self.lca(root.right, A, B) # keep traverse

        if root == A: 
            self.found_A = True
        if root == B:
            self.found_B = True

        # conquer
        if found_left is not None and found_right is not None:
            return root
        elif root in (A, B): # found root in A or B
            return root
        elif found_left:
            return found_left
        elif found_right:
            return found_right
        else:
            return None

算法說明

這已經是系列題目的第四題了,前面可參考

  • 此系列題目的第一題,由於設計上多了 parent node,相對來說比較沒有考到 LCA 的經常考點:

https://wongwongnotes-github-io.pages.dev/python/lintcode-python-474/

  • 此系列題目的第二題,BST 與 BT 只多了比較好找數字,基本上有正確實作 LCA 其實也不用管數字排序:

https://wongwongnotes-github-io.pages.dev/python/leetcode-python-235/

  • 此系列題目的第三題,與這題的差別在於,第四題會需要再多處理 A, B 可能不存在 Tree 中的情況:

https://wongwongnotes-github-io.pages.dev/python/leetcode-python-236/

修改部分,因為這題需要多處理「不存在樹中的情況」,
我們必須徹底的 traverse 完整棵樹。

這邊使用的策略是

  • 另外建一個 class 中 global 找到的 A, B 的 bool
  • 回傳時,判斷此 node 是否為 A or B (找到的當下回傳)

之所以這樣能找到正確答案是因為,最早回傳的 A or B 會一路往上傳,
而當 parent 如果發現也是 A or B,我們透過回傳「此 root」,就可以把結果洗掉。

最近在練習程式碼本身就可以自解釋的 Coding style,可以嘗試直接閱讀程式碼理解

Reference