總結所有有關二叉樹公共祖先問題
二叉樹公共祖先
滿二叉樹最近公共祖先
將一棵無窮大滿二叉樹的結點按根結點一層一層地從左往右編號,根結點編號為1。現給定a,b為兩個結點。設計一個演算法,返回a、b最近的公共祖先的編號。注意其祖先也可能是結點本身。
測試樣例:
2,3
返回:1
連結:https://www.nowcoder.com/questionTerminal/70e00e490b454006976c1fdf47f155d9
來源:牛客網
思路
因為是按照0,1,2,3這樣的滿二叉樹,所以可以直接用公式找到其父親節點
找到最低層的那個節點,然後向上找兩個節點的父節點,判斷兩者父親節點是否相同
程式碼
import java.util.*;
public class LCA {
public int getLCA(int a, int b) {
if(a > b) {
int tmp = a;
a = b;
b = tmp;
}
if(a == b) return a;
//b最大了
while(a != b) {
b = b/2;
if(b < a) {
a = a/2;
if(a == b) break;
}
}
return a;
}
}
二叉搜尋樹的最近公共祖先
給定一個二叉搜尋樹, 找到該樹中兩個指定節點的最近公共祖先。
百度百科中最近公共祖先的定義為:“對於有根樹 T 的兩個結點 p、q,最近公共祖先表示為一個結點 x,滿足 x 是 p、q 的祖先且 x
的深度儘可能大(一個節點也可以是它自己的祖先)。”例如,給定如下二叉搜尋樹: root = [6,2,8,0,4,7,9,null,null,3,5]
示例 1:
輸入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8 輸出: 6 解釋: 節點 2
和節點 8 的最近公共祖先是 6。 示例 2:輸入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4 輸出: 2 解釋: 節點 2
和節點 4 的最近公共祖先是 2, 因為根據定義最近公共祖先節點可以為節點本身。說明:
所有節點的值都是唯一的。 p、q 為不同節點且均存在於給定的二叉搜尋樹中。
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-zui-jin-gong-gong-zu-xian-lcof
思路
若 root.val < p.val,則 p 在 root 右子樹 中;
若 root.val > p.val,則 p 在 root 左子樹 中;
若 root.val = p.val ,則 p 和 root 指向 同一節點 。
程式碼-遍歷
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
while(true) {
if(root.val > p.val && root.val > q.val) {
root = root.left;
}else if(root.val < p.val && root.val < q.val) {
root = root.right;
}else break;
}
return root;
}
}
程式碼-遞迴
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root.val < p.val && root.val < q.val)
return lowestCommonAncestor(root.right, p, q);
if(root.val > p.val && root.val > q.val)
return lowestCommonAncestor(root.left, p, q);
return root;
}
}
二叉樹的最近公共祖先
給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先。
百度百科中最近公共祖先的定義為:“對於有根樹 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 為不同節點且均存在於給定的二叉樹中。
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof
思路
- 根節點本身是否是p或者q當中的某個節點
- 遞迴根的左和根的右
2.1 左右兩邊都不為空:root是公共祖先
2.2 左邊不為空,右邊為空:左邊第一次找到的節點就是公共祖先
2.3 左邊為空,右邊不為空:右邊第一個節點就是公共祖先 - 如果都沒有,則返回null
程式碼-遞迴
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null) return null;
if(root == q || root == p) 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) return left;
if(right != null) return right;
return null;
}
}