BM38. [在二叉树中找到两个节点的最近公共祖先]

alt

https://www.nowcoder.com/exam/oj?tab=%E7%AE%97%E6%B3%95%E7%AF%87&topicId=295

BM38. 在二叉树中找到两个节点的最近公共祖先

https://www.nowcoder.com/practice/e0cc33a83afe4530bcec46eba3325116?tpId=295&sfm=github&channel=nowcoder

根据题目直接上模板就可以了

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

    int left = lowestCommonAncestor(root.left, p, q);
    int right = lowestCommonAncestor(root.right, p, q);
}

然后看题目公共祖先的定义也就是从当前节点出发,在当前节点可以左子树可以找到一个点,在有子树可以找到一个点。节点本身可以视为自己的祖先。

img

比如5和1的最近公共祖先就是3

5和6的最近公共祖先就是5

7和0的最近公共祖先就是3

思考一下是不是我们从上到下遍历二叉树,如果当前节点等于两个子节点其中的一个那么这个节点就是最近公共祖先,因为另一个节点不是存在他的左子树就是存在他的右子树。所以我们继续左右子树找和目标节点1和目标节点2相等的点。那么接下来就有出现三种情况

  1. 目标1在左子树,目标2在有子树
  2. 目标1和2都在左子树
  3. 目标1和3都在有子树
  4. 因为肯定存在这样的两个点所以不会出现都不在的情况

其实我们可以将上面情况抽象为两大类
第一类是和当前节点有关系,所以判断和当前节点是否相等
第二类当前节点没有关系受到左右子树的结果影响

由于我们我们返回的是找到的其中的一个节点的值的位置,数据范围0<=节点值<=10000,所以我们可以将没有找到这个节点值返回-1

public int lowestCommonAncestor (TreeNode root, int p, int q) {
    if(root == null)
      return -1;
    //找到了任意一个值就可以返回证明有值在这个子树
    if (p == root.val || q == root.val) {
      return root.val;
    }
    // 如果公共祖先在左侧,那么就输出左面的点即可
    int left = lowestCommonAncestor(root.left, p, q);
    int right = lowestCommonAncestor(root.right, p, q);
    if(left > 0 && right == -1)
      return left;
    if(right > 0 && left == -1)
      return right;
    if(left > -1 && right > -1)
        return root.val;
    return -1;
  }

复杂度分析:

  • 时间复杂度:,其中为节点数,递归遍历二叉树每一个节点
  • 空间复杂度:,最坏情况二叉树化为链表,深度为,递归栈深度为

alt

#面经##题解##面试题目#
全部评论

相关推荐

【面试问题】1.&nbsp;请先做一下自我介绍。项目6.&nbsp;在模型应用侧,你们对模型做过哪些优化或调整?7.&nbsp;如果要做领域特定的优化,你了解哪些通用方法和技术原理?8.&nbsp;针对你们的场景,提示工程可以深入做哪些事情?9.&nbsp;RAG&nbsp;的原理能否介绍一下?10.&nbsp;向量搜索怎么去提高效率?11.&nbsp;目前微调有哪些方法?12.&nbsp;综合考虑效果与时间成本,哪种微调方法比较好?还有哪些额外措施能进一步降低时间成本?13.&nbsp;从安全视角看,大模型应用存在哪些安全风险或威胁场景?14.&nbsp;如果从安全去做能力治理、防护和检测,有哪些思路?15.&nbsp;如果要做一个在线的恶意分类模型,有什么思路或注意事项?16.&nbsp;你们用过哪些框架或平台搭建大模型应用?17.&nbsp;平时开发中常用的开发语言、框架有哪些?18.&nbsp;C++&nbsp;对象在内存中的结构大概是怎样的?19.&nbsp;内存对齐的作用是什么?20.&nbsp;CPU&nbsp;为什么会因为内存不对齐而取两次数据?原理是什么?21.&nbsp;Go&nbsp;里的协程与其他线程或进程的差异是什么?22.&nbsp;哈希表的查询效率/时间复杂度是多少?23.&nbsp;在&nbsp;Go&nbsp;里如何并发安全地访问哈希表?24.&nbsp;如果要做性能优化,有哪些办法?25.&nbsp;有哪些通用方法可以进一步减小锁的粒度?26.&nbsp;你们有哪些静态或动态手段/工具能提前避免内存泄漏(UAF)问题?28.&nbsp;除此之外,还有哪些你觉得做得比较好、有亮点的项目?手撕:27.&nbsp;合并两个有序单向链表
发面经攒人品
点赞 评论 收藏
分享
timeline:一面&nbsp;9/10自我介绍实习挖掘项目挖掘:Embedding时用到的向量数据库,文章解析和分块的功能等,ES的原理,召回的策略实习比较大的挑战和难点是什么项目关于Redis有用到哪些情景Redis是内存数据库,有什么机制去防止数据丢失(RDB,AOF)Redis如何处理过期的情况Redis有哪些具体的数据结构介绍一下BitMap介绍一下ZSet提到了ZSet用于排行榜,如果相同分数但是我想让先达到这个分数的人排在前面,如何设计(加时间戳的综合score)ZSet的底层实现是什么样的,讲解一下数据库中有比较大的表,如何进行分表,比较的依据有哪些数据库事务的特性ACID介绍一下索引,索引和事务的关联手撕:lc485,最大连续1的个数二面&nbsp;9/19自我介绍问实习项目用kafka用在了哪里为什么选用kafka,不用其他的消息队列为什么文件上传这种轻量的要用kafka消息队列的丢失如何处理如何监控是否上传成功告警的频率以及如何设置的,是埋点还是别的是实时的数据吗还是离线的数据同步看板是利用了什么方式如果看板数据无穷无尽的话grafana搞不定怎么解决kafka发送一条消息到消费经历什么过程如果超过最大处理次数都没有成功会怎样手撕:lc109:有序链表转换二叉搜索树三面10/9自我介绍问实习提示词优化了什么,技术难点校验规则变化了怎么处理XXL-Job讲一下怎么用的XXL-Job的推和拉,有什么区别哪个好手撕:lc581:最短无序连续子数组hr面&nbsp;10/14意向&nbsp;10/21感谢字节收留
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务