236. 二叉树的最近公共祖先
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 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。因为根据定义最近公共祖先节点可以为节点本身。
这道题的思路其实很简单。。。
而且和顺序有关,比如我很可能其中一个节点就是另一个节点的父亲,比如2是4的爹
那么其实我们用 中 -》左-》右的遍历,如果遍历中的时候如果发现中就是其中一个值
比如输入为[2,4] ,遍历的时候按2\7\4顺序,遍历到2时候发现,哎你不就是[2,4]的其中一个,返回你就可以了。
接下来处理不是的情况,比如输入是7和4,上图的话应该祖先是2 ,,那么我们想想,如果遍历2的时候,假如2的左子树存在[7,4]中的一个的同时,右子树也存在一个[7,4]的值(题目说了不会有重复数字),说明2绝壁就是公共祖先,那么2是不是最近的祖先?因为我们按中->左-》右顺序遍历,所以遍历到左和右的时候是一旦找到就马上返回,2绝对是最近的。
代码如下:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root==null) return null;
//中
if(root.val == p.val || root.val == q.val) return root;
//左
TreeNode left = lowestCommonAncestor(root.left ,p,q);
//右
TreeNode right = lowestCommonAncestor(root.right ,p,q);
//左右都不为空,你就是啦
if(left!=null&&right!=null) return root;
//不是我自己那么最近的肯定在左边或者右边
return left!=null?left:right;
}
}
变体:
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 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
, 因为根据定义最近公共祖先节点可以为节点本身。
这个思路也很绝,直接上代码,但是遍历的时候忘记写return!!!!两个return都没写到导致错误,【二叉树遍历左右的时候容易忘记return或者不该retrun的时候赋值!!!这个要注意不要踩坑了!!!!!!!!!!!!!】
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// 先排个序呗,大的在前,小的在后
return lowestCommonAncestor(root, Math.max(p.val, q.val), Math.min(p.val, q.val));
}
public TreeNode lowestCommonAncestor(TreeNode root,int max,int min){
if(root==null) return null;
if(root.val > max){
//左子树找去
return lowestCommonAncestor(root.left, max,min); //忘记写return
}
if(root.val < min){
return lowestCommonAncestor(root.right,max,min); //忘记写rerturn
}
//说明大于等于min,小于等于max,说明啥,这是祖先啊!
return root;
}
}