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

class Solution:def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':def dfs(root: 'TreeNode', p: 'TreeNode', q: 'TreeNode'):# 如果当前节点为空,则说明 p、q 不在 node 的子树中,不可能为公共祖先,直接返回 Noneif not root:return None# 如果当前节点 root 等于 p 或者 q,那么 root 就是 p、q 的最近公共祖先,直接返回 root,不需要遍历子树了if root == p or root == q:return root# 递归遍历左子树、右子树,并判断左右子树结果node_left = dfs(root.left, p, q)node_right = dfs(root.right, p, q)# 如果左右子树都不为空,则说明 p、q 在当前根节点的两侧,当前根节点就是他们的最近公共祖先if node_left and node_right:return rootreturn node_left if node_left else node_rightans = dfs(root, p, q)return ans

在递归函数 dfs 中,我们是先判断 root 是否等于 p 或者 q,再遍历其左右子树,这样可以应对两种情况:1、p 或者 q 在最近公共祖先的两侧,此时由于祖先作为 root 不等于p、q,所以左右子树都会被遍历,从而逐级向上返回,得到祖先的左右子树都不为空,返回 root;2、
p 或者 q 自身就是最近公共祖先,此时满足 root 等于 p 或 q,直接返回 root 即可。

1676. 二叉树的最近公共祖先 IV

class Solution:def lowestCommonAncestor(self, root: 'TreeNode', nodes: 'List[TreeNode]') -> 'TreeNode':def dfs(root: 'TreeNode', nodes: 'List[TreeNode]'):# 如果当前节点为空,则说明 p、q 不在 node 的子树中,不可能为公共祖先,直接返回 None,不需要遍历子树了if not root:return None# 如果当前节点 root 等于 p 或者 q,那么 root 就是 p、q 的最近公共祖先,直接返回 rootfor node in nodes:if root == node:return root# 递归遍历左子树、右子树,并判断左右子树结果node_left = self.dfs(root.left, nodes)node_right = self.dfs(root.right, nodes)# 如果左右子树都不为空,则说明 p、q 在当前根节点的两侧,当前根节点就是他们的最近公共祖先if node_left and node_right:return rootreturn node_left if node_left else node_rightans = dfs(root, nodes)return ans

与上一题同理,此题 p、q 换成了更多的节点,用列表 nodes 表示。

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

class Solution:def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':def dfs(root: 'TreeNode', p: 'TreeNode', q: 'TreeNode'):nonlocal pFlagnonlocal qFlag# 如果当前节点为空,则说明 p、q 不在 node 的子树中,不可能为公共祖先,直接返回 Noneif not root:return None# 递归遍历左子树、右子树,并判断左右子树结果node_left = dfs(root.left, p, q)node_right = dfs(root.right, p, q)# 如果左右子树都不为空,则说明 p、q 在当前根节点的两侧,当前根节点就是他们的最近公共祖先if node_left and node_right:return root# 如果当前节点 root 等于 p 或者 q,那么 root 就是 p、q 的最近公共祖先,返回 root,子树也已经被遍历过了if root == p or root == q:if root == p:pFlag = Trueif root == q:qFlag = Truereturn rootreturn node_left if node_left else node_rightpFlag = FalseqFlag = Falseans = dfs(root, p, q)if not pFlag or not qFlag:return Nonereturn ans

这题需要用两个标志位记录 p 和 q 有没有出现过,如果其中之一没出现过就返回 None。这题的判断 root 是否等于 p 或 q 要放在遍历左右子树的后面,这是因为如果 root 等于 p 或 q 了然后返回,此时只有一个标志位是变成 True 的,但我们要两个标志位都为 True 时才返回 ans。所以我们要先遍历左右子树,再判断 root 的值,这样就会遍历到所有的节点,这种写法在前面两题也可以使用,但是在前面两题的情况下是属于效率低的。

二叉树最近公共祖先相关题目(Leetcode题解-Python语言)相关推荐

  1. 二叉树序列化与反序列化相关题目(Leetcode题解-Python语言)

    297. 二叉树的序列化与反序列化(剑指 Offer 37. 序列化二叉树)(剑指 Offer II 048. 序列化与反序列化二叉树) class Codec:def serialize(self, ...

  2. 二叉树层序遍历(广度优先搜索)基础概念与经典题目(Leetcode题解-Python语言)

    二叉树的广度优先搜索即从上到下.从左到右地进行搜索,对于层序遍历(Level Order)问题,即依次遍历第一层节点.第二层节点-等,基本可以秒杀. 广度优先搜索是通过队列来实现的,python中优先 ...

  3. 两数、三数、四数之和相关题目(Leetcode题解-Python语言)

    作为 Leetcode 的第一题,两数之和自然是知名度最高的,从两数之和出发也有不少的衍生题目,下面就让我们好好地解决它们. 1. 两数之和 class Solution:def twoSum(sel ...

  4. 快速幂算法相关题目(Leetcode题解-Python语言)

    50. Pow(x, n) 快速幂算法的目的,就是快速计算 x 的 n 次方.基本思路是把 n 视作二进制数,则 n 可以被分解为多个 2 的幂次方之和,如 12 对应 1100 等于 0∗20+0∗ ...

  5. 爬楼梯与路径类题目记忆化递归与动态规划双解法(Leetcode题解-Python语言)

    70. 爬楼梯(剑指 Offer 10- II. 青蛙跳台阶问题) 递归(英语:Recursion),是指在函数的定义中使用函数自身的方法.有意义的递归通常会把问题分解成规模缩小的同类子问题,当子问题 ...

  6. 链表基础概念与经典题目(Leetcode题解-Python语言)

    所谓链表,就是由链节点元素组成的表,那什么是链节点呢?直接上定义: class ListNode:def __init__(self, val=0, next=None):self.val = val ...

  7. 高度平衡的二叉搜索树基础概念与经典题目(Leetcode题解-Python语言)

    高度平衡的二叉搜索树(平衡二叉树),定义见此Leetbook.简单来说,就是基于相同节点值构建出来的二叉搜索树中高度最小的,即为平衡二叉树(不唯一).有 N 个节点的平衡二叉搜索树,它的高度是 log ...

  8. 二分查找基础概念与经典题目(Leetcode题解-Python语言)二分索引型

    二分查找的定义如下(引自Wiki): 在计算机科学中,二分查找算法(英语:binary search algorithm),也称折半搜索算法(英语:half-interval search algor ...

  9. 字符串经典题目(Leetcode题解-Python语言)

    344. 反转字符串 class Solution:def reverseString(self, s: List[str]) -> None:"""Do not ...

最新文章

  1. CentOS 命令提示符颜色及样式详解
  2. 社区O2O的发展与未来
  3. 语言模型GPT-2挤牙膏式开源,放出774M预训练模型,称是倒数第二版
  4. 程序人生【一些经典的资料】
  5. IIS启动时出现0x8ffe2740的错误
  6. 【转载】比特币入门教程
  7. HDU 4893 - Wow! Such Sequence!(线段树)
  8. Linux centos查看cpu信息命令
  9. C# 微支付退款申请接口 V3.3.6
  10. Docker 入门(4)镜像与容器
  11. CListBox的函数
  12. bzoj 3881 [Coci2015]Divljak——LCT维护parent树链并
  13. 再问数据中台 - 数据中台和业务中台服务有什么区别 应该如何去界定和划分?
  14. cross apply
  15. Excel函数(4)日期、文本函数
  16. 加快onenote同步速度
  17. 长沙南站启动脸部识别验证验票;奔驰和美国无人机物流公司公司合作用无人机配送商品...
  18. centos gedit 字体大小_【写作技巧】毕业论文格式要求及字体大小
  19. jQuery weui Select组件显示指定值
  20. 鏖战双十一:阿里直播平台面临的技术挑战

热门文章

  1. oracle 网关下载,oracle透明网关访问sqlserver2000
  2. 六台机器搭建RedisCluster分布式集群
  3. Android之提示Unable to get provider com.google.android.gms.ads.MobileAdsInitProvider
  4. 剑指offer之二维数组中查找
  5. LeetCode之Rotate Array
  6. C语言之rand()和srand()函数
  7. 栈和队列之设计一个有getMin(得到最小值)功能的栈
  8. layui 数字步进器_图解全新奔驰S级:从“传统豪华”向“数字豪华”转型
  9. java23种设计模式个人整理_java23种设计模式-行为型模式之模板方法模式
  10. 男人的快乐可以多简单?