deflowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode: if check_same_subtree(p, q): return p elif check_same_subtree(q, p): return q
deffind_parent(root): if root isNone: returnFalse if root == p or root == q: returnTrue left = find_parent(root.left) right = find_parent(root.right)
# 如果左右子樹都有找到,代表當前的root就是答案 if left and right: self.ans = root # 如果左右子樹有一個找到,代表還不夠高,繼續往上找 elif left or right: returnTrue # 如果左右子樹都沒有找到,回傳False else: returnFalse
defcheck_same_subtree(parent, child): if parent isNone: returnFalse if parent == child: returnTrue return check_same_subtree(parent.left, child) or check_same_subtree(parent.right, child)
deffind_parent(root): if root isNone: returnFalse if root == p or root == q: returnTrue left = find_parent(root.left) right = find_parent(root.right)
# 如果左右子樹都有找到,代表當前的root就是答案 if left and right: self.ans = root # 如果左右子樹有一個找到,代表還不夠高,繼續往上找 elif left or right: returnTrue # 如果左右子樹都沒有找到,回傳False else: returnFalse
情境2: 如果發現兩邊都有值,就代表我們找到 p 跟 q 節點了,但是因為他們在不同的子樹下,所以當前的root就是祖先。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classSolution: deflowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode: # 回傳 Ture 或是 False 概念 只是都是 root if root isNoneor root == p or root == q: return root
left = self.lowestCommonAncestor(root.left, p, q) right = self.lowestCommonAncestor(root.right, p, q) # 情境2 兩邊都有值,代表找到 p 跟 q,但是在不同的子樹下 回傳當前的root if left and right: return root # 情境1 一邊有值,另一邊沒有值,回傳有值的那一邊 if left or right: return left or right
3 總結
這題的關鍵思想在於 找left subtree 跟 right subtree 是否存在 p 與 q
如果只有一邊存在,那代表 p 與 q 一定是父子關係,所以回傳最早找到的那個節點(父節點)
如果兩邊subtree各自找到 p 與 q,那代表 p 與 q 在不同的子樹下,所以回傳當前的root