1. 程式人生 > 其它 >演算法小抄學習筆記 — 7.二叉樹的最近公共祖先

演算法小抄學習筆記 — 7.二叉樹的最近公共祖先

技術標籤:labuladong演算法小抄筆記leetcode二叉樹

1 二叉樹遞迴靈魂三問

  • 這個函式應該幹什麼?
    • 函式功能
    • 正向邏輯推理
  • base case是啥?
  • 得到遞迴結果後,會做什麼?
    • 反向邏輯推理

下面使用一個題目來示例一下。



2 題目

2.1 236. 二叉樹的最近公共祖先

2.1.1 題目

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

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

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

img

示例 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。因為根據定義最近公共祖先節點可以為節點本身。

2.1.2 思路

由於是一個二叉樹的題目,直接寫上二叉樹框架應該沒有問題。

class Solution {
    public TreeNode lowestCommonAncestor
(TreeNode root, TreeNode p, TreeNode q) { TreeNode left = lowestCommonAncestor(root.left, p, q); TreeNode right = lowestCommonAncestor(root.right, p, q); } }

下面開始靈魂三問

2.1.2.1 這個函式應該幹什麼?

函式功能:找出以根節點root的樹下節點pq的最近公共祖先節點,並返回公共祖先節點。

根據函式功能進行正向邏輯推理(這裡不要把root認為是最大範圍的根節點):

  • pq都在root
    下,返回rootpq的最近公共祖先節點。
  • pq都不在root下,返回null
  • pq只有一個在root下,返回root

2.1.2.2 base case是啥?

  • root == null時,返回null
  • p == root || q == root時,返回root

2.1.2.3 得到遞迴結果後,會做什麼?

根據遞迴結果進行反向邏輯推理(這裡把root認為是最大範圍的根節點,不要陷入遞迴)

  • leftright均不為空,則root為最近公共祖先節點。
  • leftright均為空,則沒有最近公共祖先節點。
  • left != null && right == null,返回left。相反的情況,返回 right

然後就不要想這麼多了,先把程式碼寫上吧!如果出錯,肯定是三個問題哪裡沒有答好,就要回去再仔細思考一下,看看有沒有漏,記住回去想的時候最好避免陷入遞迴裡面去想

2.1.3 程式碼

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



3 參考