1. 程式人生 > 資訊 >榮耀 HONOR 宣佈:五一期間, 5 家高階體驗店將重大開業

榮耀 HONOR 宣佈:五一期間, 5 家高階體驗店將重大開業

文章目錄

二叉樹的最近公共祖先

1. 題意

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

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

在這裡插入圖片描述

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

在這裡插入圖片描述

輸入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
輸出:5
解釋:節點 5 和節點 4 的最近公共祖先是節點 5 。因為根據定義最近公共祖先節點可以為節點本身。

2. 思路

作為一個公共父節點,它應該有以下特徵:

  • 如果該節點既不是 p p p 又不是 q q q,那麼 p p p q q q 一定分別存在於 該節點的左右子樹
  • 如果該節點是其中一個節點 p p p q q q,那麼,該節點的左子樹或右子樹必然包含 q q q p p p

在官方題解中:
使用 l s o n lson lson 表示左子樹包含 p p

p q q q, 使用 r s o n rson rson 表示右子樹包含 p p p q q q
而根據以上的特徵,父節點所滿足的條件應該是:
( l s o n & & r s o n ) ∣ ∣ ( ( r o o t . v a l = = q . v a l ∣ ∣ r o o t . v a l = = p . v a l ) & & ( l s o n ∣ ∣ r s o n ) ) (lson \&\& rson) ||((root.val == q.val || root.val == p.val) \&\& (lson || rson))
(lson&&rson)((root.val==q.valroot.val==p.val)&&(lsonrson))

3. 實現

正是基於以上特徵,採用遞迴的方式進行深度優先搜尋

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    private TreeNode ans;

    public Solution() {
        this.ans = null;
    }

    private boolean dfs(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null)
            return false;

        //左右子樹是否包含 p q 節點
        boolean lson = dfs(root.left,p,q);
        boolean rson = dfs(root.right,p,q);

        if ((lson && rson) || ((root.val == q.val) || (root.val == p.val)) && (lson || rson))
            this.ans = root;

        return lson || rson || root.val == q.val || root.val == p.val;
    }

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        this.dfs(root,p,q);
        return this.ans;
    }
}

4. 轉載連結

連結: leetcode 236. 二叉樹的最近公共祖先