【面試題 04.08】 首個共同祖先

題目

題目鏈接

設計並實現一個算法,找出二叉樹中某兩個節點的第一個共同祖先。不得將其他的節點存儲在另外的數據結構中。注意:這不一定是二叉搜索樹。

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

    3
   / \
  5   1
 / \ / \
6  2 0  8
  / \
 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 爲不同節點且均存在於給定的二叉樹中。

實現思路

之前做過平衡二叉樹的最近祖先問題,但是本題特別說明不是平衡二叉樹,沒法用平衡二叉樹的規律解題。

將此題結果分爲3種情況

  1. p,q同屬於左子樹
  2. p,q同屬於右子樹
  3. p,q分別屬於左子樹和右子樹

遞歸求解
若p q同屬於左子樹 就遞歸縮小範圍到root.left 繼續尋找
若p q同屬於右子樹,就遞歸縮小範圍到root.right 繼續尋找
若p q分別屬於左子樹和右子樹,那麼直接返回root root爲祖先

代碼


/**
 * Definition for a binary tree node.
 * public class TreeNode {
 * int val;
 * TreeNode left;
 * TreeNode right;
 * TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        return solve(root, p, q);
    }

    public TreeNode solve(TreeNode root, TreeNode p, TreeNode q) {
        //pq都不屬於此子樹
        if (root == null) {
            return null;
        }
        //p或者q屬於這個子樹
        if (root == p || root == q) {
            return root;
        }
        //pq是否有一個在左子樹
        TreeNode left = solve(root.left, p, q);
        //pq是否有一個在右子樹
        TreeNode right = solve(root.right, p, q);
        //都不爲空,說明pq一左一右
        if (left != null && right != null) {
            return root;
        } else {//有一個空,說明都在左或者都在右
            //pq都在左
            if (left != null) {
                return left;
            } else {//pq都在右
                return right;
            }
        }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章