1. 程式人生 > 實用技巧 >劍指 Offer 68 - II. 二叉樹的最近公共祖先(遞迴)

劍指 Offer 68 - II. 二叉樹的最近公共祖先(遞迴)

  • 題目描述
給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先。

百度百科中最近公共祖先的定義為:“對於有根樹 T 的兩個結點 p、q,最近公共祖先表示為一個結點 x,滿足 x 是 p、q 的祖先且 x 的深度儘可能大(一個節點也可以是它自己的祖先)。”

例如,給定如下二叉樹: root =[3,5,1,6,2,0,8,null,null,7,4]

示例 1:

輸入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
輸出: 3
解釋: 節點 5 和節點 1 的最近公共祖先是節點 3。
示例2:

輸入: root 
= [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 輸出: 5 解釋: 節點 5 和節點 4 的最近公共祖先是節點 5。因為根據定義最近公共祖先節點可以為節點本身。 說明: 所有節點的值都是唯一的。 p、q 為不同節點且均存在於給定的二叉樹中。
  • 遞迴求解

有了第一題的經驗,我們其實可以分析出這道題的實質是做什麼,就是不斷遍歷root直到p和q要麼一個在根一個在葉子節點,要麼兩個都在某個root的葉子節點。

考慮通過遞迴對二叉樹進行後序遍歷,當遇到節點 pp 或 qq 時返回。從底至頂回溯,當節點 p, qp,q 在節點 rootroot 的異側時,節點 root即為最近公共祖先,則向上返回 root。

首先我們遞迴求得左右子樹left和right,然後:

1.當left和right均為空時,返回空

2.當left和right均不為空時,返回root

3.當left為空,right不為空,返回right(當p和q其中一個在root的右子樹,此時right指向其中一個;當p和q均在右子樹中,此時right則為最近公共祖先節點)

4.當right為空時,left不為空,與3相同。

class Solution:
    def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
        
if root == p or root == q or (not root): return root left = self.lowestCommonAncestor(root.left, p, q) right = self.lowestCommonAncestor(root.right, p, q) if not left: return right if not right: return left if not left and not right: return return root

時間複雜度O(N)

空間複雜度O(1)