import common.TreeNode;
/**
* 類說明
* 給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先。
百度百科中最近公共祖先的定義爲:“對於有根樹 T 的兩個結點 p、q,最近公共祖先表示爲一個結點 x,滿足 x 是 p、q 的祖先且 x 的深度儘可能大(一個節點也可以是它自己的祖先)。”
例如,給定如下二叉樹: root = [3,5,1,6,2,0,8,null,null,7,4]
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
* <pre>
* Modify Information:
* Author Date Description
* ============ =========== ============================
* wangm 2020年5月11日 Create this file
* </pre>
*
*/
public class LeetCode236 {
/**
* 思路1: 如果節點有父節點指針的話,這樣你能保留這個路徑,LCA lowestCommonAcesstor 找最短公共路徑
* 思路2: 思路驚奇: root 節點, 如果 q 節點在 左子樹,p 在root 的右子樹,那麼 root 就是 q p 公共父親。
* 如果左子樹沒找到 p, 也沒找到 q 返回的是個 null, 那麼 就在右子樹上
* 如果右子樹沒找到 p, 也沒找到 q 返回的是個 null,那麼就在左子樹上
* @param root
* @param p
* @param q
* @return
*/
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// 如果 root 爲 null 那麼返回 null
// 如果 p 或者 q 就已經在根節點上了,那最短路徑父親就是 q 或者 p
if(root == null || root == p || root == q) return root;
// 從root 節點的左子樹開始找
TreeNode left = lowestCommonAncestor(root.left, p, q);
// 從 root 節點的右子樹開始找
TreeNode right = lowestCommonAncestor(root.right, p, q);
// 如果有一個時刻,發現 root 節點的左子樹包含p/q 右子樹包含 q/p 那麼 root 就是最短父親。
if(left != null && right != null){
return root;
}
// 如果有一個時刻,發現 右子樹沒找到 p/q,那麼 父親肯定在 左子樹上找到
if(right == null){
return left;
}
// 如果有一個時刻,發現左子樹上 沒找到 p/q,那麼 父親肯定在 右子樹上找到
return right;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}