[剑指offer]面试题第[68-1]题[Leedcode][JAVA][第235题][二叉搜索树的最近公共祖先][递归][BFS]

239 篇文章 1 订阅
【问题描述】[第235题][二叉搜索树的最近公共祖先][简单]
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 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。

在这里插入图片描述

【解答思路】
1. 递归 后续遍历

由于是二叉搜索树,所以找最近的共同祖先比较容易,总共就三种情况。

  • 如果给定的两个节点的值都小于根节点的值,那么最近的共同祖先一定在左子树
  • 如果给定的两个节点的值都大于根节点的值,那么最近的共同祖先一定在右子树
  • 如果一个大于等于、一个小于等于根节点的值,那么当前根节点就是最近的共同祖先了
    至于前两种情况用递归继续去解决即可。

通过交换使得 p.val <= q.val ,这样就可以简化后边 if 语句的判断
时间复杂度:O(N) 空间复杂度:O(N)

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {

    // 保持 p.val <= q.val
    if (p.val > q.val) {
        return lowestCommonAncestor(root, q, p);
    }
    //如果有一个是根节点就可以提前结束, 当然这个 if 不要也可以
    if (p.val == root.val || q.val == root.val) {
        return root;
    }
    if (q.val < root.val) {
        return lowestCommonAncestor(root.left, p, q);
    } else if (p.val > root.val) {
        return lowestCommonAncestor(root.right, p, q);
    } else {
        return root;
    }

}

2. 迭代

找到分割点就可以了。这个分割点就是能让节点 p和节点 q不能在同一颗子树上的那个节点,或者是节点 p 和节点 q中的一个,这种情况下其中一个节点是另一个节点的父亲节点

时间复杂度:O(N) 空间复杂度:O(1)

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    int pVal = p.val;
    int qVal = q.val;
    if (pVal == root.val || qVal == root.val) {
        return root;
    }
    // 保持 p.val <= q.val
    if (pVal > qVal) {
        int temp = pVal;
        pVal = qVal;
        qVal = temp;
    }
    while (true) {
        if (qVal < root.val) {
            root = root.left;
        } else if (pVal > root.val) {
            root = root.right;
        } else {
            return root;
        }
    }
}

【总结】
1.二叉搜索树定义
  • 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
  • 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
  • 任意节点的左、右子树也分别为二叉查找树;
  • 没有键值相等的节点。
2.二叉树遍历

前序遍历 先输出当前结点的数据,再依次遍历输出左结点和右结点
中序遍历 先遍历输出左结点,再输出当前结点的数据,再遍历输出右结点
后续遍历 先遍历输出左结点,再遍历输出右结点,最后输出当前结点的数据

3. 中序遍历输出的是一个升序数组
4. 对于二叉树的题,开始可以用递归的思想去思考会比较简单

相关题目 236

转载链接:https://leetcode.wang/leetcode-235-Lowest-Common-Ancestor-of-a-Binary-Search-Tree.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值