榮耀 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
而根據以上的特徵,父節點所滿足的條件應該是:
(
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))
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;
}
}