給定一個二叉搜索樹, 找到該樹中兩個指定節點的最近公共祖先。
百度百科中最近公共祖先的定義爲:“對於有根樹 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
, 因爲根據定義最近公共祖先節點可以爲節點本身。
先來說明二叉搜索樹的性質,其左子樹上的結點都小於根結點,右子樹上的結點都大於根節點。並且左右子樹都是二叉搜索樹
利用遞歸進行求解
/**
* 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) {
if(p.val<root.val && q.val < root.val){
return lowestCommonAncestor(root.left,p,q);//在左子樹找
}
if(p.val>root.val && q.val > root.val){
return lowestCommonAncestor(root.right,p,q);//在右子樹找
}
return root;//如果左右子樹都沒有滿足的公共結點,則root就是公共結點。
}
}
難度簡單52
給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先。
百度百科中最近公共祖先的定義爲:“對於有根樹 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 爲不同節點且均存在於給定的二叉樹中。
解題思路:通過路徑打印,然後在路徑中找到第一個相等的值就是最近的公共祖先了。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public static boolean getPath(TreeNode root,TreeNode node,Stack<TreeNode> stack){
if(root == null)
return false;
stack.push(root);
if(root == node)
return true;
if(getPath(root.left,node,stack))
return true;
if(getPath(root.right,node,stack))
return true;
stack.pop();//當前結點既不是node結點,而且他的左右子樹也沒有這個結點,所以這個結點不在node的路徑上,所以就從棧中刪除當前結點。
return false;
}
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
Stack<TreeNode> stack1 = new Stack<>();
Stack<TreeNode> stack2 = new Stack<>();
getPath(root,p,stack1);
getPath(root,q,stack2);
while(stack1.size() != stack2.size()){
if(stack1.size()>stack2.size()){
stack1.pop();
}else{
stack2.pop();
}
}
while(stack1.size() != 0){
if(stack2.peek() == stack1.peek()){
break;
}else{
stack1.pop();
stack2.pop();
}
}
return stack1.peek();
}
}