劍指 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 為不同節點且均存在於給定的二叉樹中。

遞迴思想

演算法流程:

1.終止條件:

  • 如果root樹根節點為空或者越節點,直接返回空
  • 如果root等於p、q,則返回root

2.遞迴條件:

  • 開啟遞迴左節點,返回left
  • 遞迴右節點同理

3.返回值

當left和right都不為空的時候,說明left和right在root節點異端,直接返回root即為二叉樹最近的公共祖先

當left為空,則直接返回right,說明有可能p,q有一個在右節點樹

當right為空,則直接返回left,同上理

class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null) return null;
if(root.val == p.val || root.val == q.val) return root; TreeNode findLeft = lowestCommonAncestor(root.left, p, q);
TreeNode findRight = lowestCommonAncestor(root.right, p, q); if(findLeft != null && findRight != null)
return root;
else if(findLeft == null)
return findRight;
else
return findLeft;
}
}

以下程式碼是k神更為簡潔易懂的程式碼:情況 1. , 2. , 3. , 4. 的展開寫法如下。

class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null || root == p || root == q) return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if(left == null && right == null) return null; // 1.
if(left == null) return right; // 3.
if(right == null) return left; // 4.
return root; // 2. if(left != null and right != null)
}
}

參考連結:

https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/solution/mian-shi-ti-68-ii-er-cha-shu-de-zui-jin-gong-gon-7/