【LeetCode】升级打怪之路 Day 21:二叉树的最近公共祖先(LCA)问题

今日题目:

今天做了几道有关二叉树的最近公关祖先(LCA)问题,没有接触过的话,直接上手就能解答出来还是存在不少困难的。今天学习了相关的解题思路,寻找 LCA 问题的框架在本质上还是一个二叉树递归遍历的框架。重点需要把握好代码实现中辅助函数 find() 的语义,以及为什么这样实现。根据 LCA 可能出现的情况,实现 LCA 的寻找

LCA 问题

最近公共祖先(Lowest Common Ancestor,LCA)问题是一类问题,这类题目也存在一定的难度,因此需要认真学习一下。

labuladong 的 Git原理之最近公共祖先 这篇文章介绍了 LCA 问题的解题思路,可以参考学习一下。

LC 236. 二叉树的最近公共祖先 【classic】

236. 二叉树的最近公共祖先

这个题目就是经典的 LCA 问题。

我们想要找 p 和 q 的 LCA,那这个 LCA 有两种情况:

  • case 1:自己是 p 或 q,另一个在自己的子树上(或者也还是自己)
  • case 2:自己不是 p 或 q,其中一个在自己左子树上,另一个在自己右子树上

对于寻找 LCA 的问题,我们可以写一个 find() 辅助函数来完成递归寻找。

我们需要明确一下 find() 函数的语义:它从 root 开始寻找它认为最可能是 LCA 的节点。这里限定是“最可能”是因为,在 case 1 中,如果一个节点发现自己是 p 或 q,那它就不需要再向下找了,因为从自己这个层次上来看, 如果有 LCA 的话,那也只能是自己,不可能是再向下的子树中的节点了。至于真的是不是 LCA,就交由更上层的节点来验证,如果更上层的节点没有再找到另一个 p 或 q,那就是了。所以 find 函数只需要返回当前这个节点自认为最可能是 LCA 的节点就可以。来看代码:

236 题目

可以看到,find() 函数就是返回一个节点在自己层级上所认为的最可能是 LCA 的节点。因为题目说了一定存在 p 和 q,也就是一定存在 LCA,所以最终返回的就是 root 所认为的最可能是 LCA 的节点,它是一定存在的。

LC 1644. 二叉树的最近公共祖先 II 【稍有难度】

1644. 二叉树的最近公共祖先 II

这个题目相比于上个题目有了变动,上一个题目明确说了一定存在 LCA,但这个题目却不一定,所以在这题目中,我们无法肯定 find() 函数返回的最终结果就是 LCA,需要加一个标志位用来区分是否真的找到了 LCA。

在之前的 find() 函数的逻辑中,当一个节点自己就等于 p 或 q 之一时就返回自己作为可能的 LCA,没有再向下确定自己的子树中是否还存在另一个目标值,从而导致了这种不确定性。因为我们的遍历本质上是后序递归遍历,所以遍历一定是遍历了所有节点,也就是如果存在 p 或 q,我们是一定能遍历到的,所以我们可以加一个标志位来记录是否找到了 p 和 q。如果最终标志位说明找到了 p 和 q,那 find() 函数返回的 TreeNode 就是我们要找的 LCA 节点了。

所以这个题目的解法相比于上个题目,主要是加了个标志位:

1644
可以看到,代码整体思路与之前的一样,只是加了个标志位,用来判断最终找到的结果是不是 LCA。

LC 235. 二叉搜索树的最近公共祖先 ⭐⭐⭐

235. 二叉搜索树的最近公共祖先

这个题目也是个变形。将二叉树改为二叉搜索树,需要利用上 BST 的相关特性。

其实只当它是个二叉树的话,之前的题目的解法也能做这个题目,这个题目的难点在于如何利用上 BST 的特性。

因为我们的 find() 本质上还是递归遍历寻找目标值,如果是在 BST 上进行遍历的话,我们可以利用目标值的大小和当前值的大小进行对比,从而避免向不可能存在目标值的分支上进行查找。

为了实现“剪枝”的效果,我们这一次 find() 函数的实现中,将判断是否自己是 LCA 逻辑放到了递归之前,也就是前序的位置,这样的话,如果根据某些条件来决定出哪个子树不需要递归下去了。

代码思路及实现如下:

235 代码

做了这个题,我们就可以对寻找 LCA 问题有了更深的理解。

相关推荐

  1. LeetCode236.最近公共祖先

    2024-03-15 04:22:02       7 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-15 04:22:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-15 04:22:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-15 04:22:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-15 04:22:02       18 阅读

热门阅读

  1. 【点云】激光点云建图评测

    2024-03-15 04:22:02       18 阅读
  2. OpenAI GPT-4.5 Turbo 泄露,六月或将发布

    2024-03-15 04:22:02       20 阅读
  3. 4. git 添加版本标签

    2024-03-15 04:22:02       21 阅读
  4. Oracle控制文件control file(1)控制文件概述

    2024-03-15 04:22:02       21 阅读
  5. 电子信息工程实践案例分析报告

    2024-03-15 04:22:02       20 阅读
  6. PHP伪协议详解

    2024-03-15 04:22:02       22 阅读
  7. LeetCode(力扣)算法题_2864_最大二进制奇数

    2024-03-15 04:22:02       19 阅读
  8. 2.Linux文件IO基础

    2024-03-15 04:22:02       20 阅读
  9. 查看Linux服务器配置

    2024-03-15 04:22:02       22 阅读
  10. leetcode:反转链表II 和k个一组反转链表的C++实现

    2024-03-15 04:22:02       22 阅读
  11. 网络学习DAY3--TCP并发

    2024-03-15 04:22:02       20 阅读
  12. LeetCode2864. Maximum Odd Binary Number

    2024-03-15 04:22:02       25 阅读
  13. 动态规划 Leetcode 494 目标和

    2024-03-15 04:22:02       20 阅读
  14. 缓存穿透和缓存击穿有什么区别?

    2024-03-15 04:22:02       22 阅读