首页 > 其他分享 >26.二叉树的最近公共祖先

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

时间:2023-09-07 20:33:09浏览次数:32  
标签:26 right TreeNode 祖先 二叉树 null root 节点 left

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

1、概要

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

说明:

  • 所有节点的值都是唯一的。
  • p、q 为不同节点且均存在于给定的二叉树中。

首先想的是要是能自底向上查找就好了,这样就可以找到公共祖先了。二叉树回溯的过程就是从低到上。

后序遍历(左右中)就是天然的回溯过程,可以根据左右子树的返回值,来处理中节点的逻辑。

如何判断一个节点是节点q和节点p的公共祖先呢。

判断逻辑是 如果递归遍历遇到q,就将q返回,遇到p 就将p返回,那么如果 左右子树的返回值都不为空,说明此时的中节点,一定是q 和p 的最近祖先。容易忽略一个情况,就是节点本身p(q),它拥有一个子孙节点q(p)

2、思路

递归

  • 确定递归函数返回值以及参数

需要返回,告诉是否找到两个节点,bool类型就可以。但还要返回最近公共节点,所以遇到p,q返回,不为空也说明找到了。

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q)
  • 确定终止条件

遇到空,树空了,如果找到p,q,将其返回,中节点处理会用到。

if (root == null || root == p || root == q) { // 递归结束条件
            return root;
        }
  • 确定单层递归逻辑

有返回值,回溯过程需要递归函数的返回值判断。需要遍历树的所有节点

在递归函数有返回值的情况下:如果要搜索一条边,递归函数返回值不为空的时候,立刻返回,如果搜索整个树,直接用一个变量left、right接住返回值,这个left、right后序还有逻辑处理的需要,也就是后序遍历中处理中间节点的逻辑(也是回溯)

为什么要遍历整棵树呢?直观上来看,在左边找到最近公共祖先,直接一路返回就可以了。

但事实上还要遍历根节点右子树(即使此时已经找到了目标节点了)

因为在如下代码的后序遍历中,如果想利用left和right做逻辑处理, 不能立刻返回,而是要等left与right逻辑处理完之后才能返回。

如果left 和 right都不为空,说明此时root就是最近公共节点。这个比较好理解

如果left为空,right不为空,就返回right,说明目标节点是通过right返回的,反之依然

image-20230907162137883

图中节点10的左子树返回null,右子树返回目标值7,那么此时节点10的处理逻辑就是把右子树的返回值(最近公共祖先7)返回上去!

那么如果left和right都为空,则返回left或者right都是可以的,也就是返回空。

// 后序遍历
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);

        if(left == null && right == null) { // 若未找到节点 p 或 q
            return null;
        }else if(left == null && right != null) { // 若找到一个节点
            return right;
        }else if(left != null && right == null) { // 若找到一个节点
            return left;
        }else { // 若找到两个节点
            return root;
        }

迭代

没有给出迭代法,因为迭代法不适合模拟回溯的过程。理解递归的解法就够了

3、代码

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null || root == p || root == q){
            return root;
        }

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

        if(left == null && right== null){// 若未找到节点 p 或 q
            return null;
        }else if(left == null && right != null){ // 若找到一个节点,在右边
            return right;
        }else if(left != null && right == null){// 若找到一个节点,在左边
            return left;
        }else { // 若找到两个节点
            return root;
        }
    }
}

标签:26,right,TreeNode,祖先,二叉树,null,root,节点,left
From: https://www.cnblogs.com/autumnmoonming/p/17685984.html

相关文章

  • 《Java编程思想第四版》学习笔记26
    //:Cleanup.java//Payingattentiontoexceptions//inconstructorsimportjava.io.*;classInputFile{privateBufferedReaderin;InputFile(Stringfname)throwsException{try{in=newBufferedReader(......
  • CF1266D
    原题翻译其实这题的翻译反而不如原题好理解,建议先阅读原题后重新思考做法         \[\large{\color{#ff0000}{\text{分割线}}}\]                        翻译把原来简单的东西复杂了原题的题意是有若......
  • 码流格式: Annex-B, AVCC(H.264)与HVCC(H.265), extradata详解(转)
    原文:http://www.taodudu.cc/news/show-6091235.html?action=onClick1.前言介绍H.264结构的文章铺天盖地,无责任翻译、无责任转载以及部分经验之谈(目前搜索最靠前的一篇实际是对stackoverflow上答案的翻译。。链接后面给出了),所以缺的不是资料,是叙述准确的资料。来吧,看这篇整理就够......
  • SI3262是13.56MHZsoc刷卡芯片集成集成刷卡+触摸+ACD超低功耗门锁方案
    13.56mhz刷卡soc芯片SI3262集成刷卡+触摸+ACD超低功耗,ACD模式刷卡距离可达到5cm以上,非常适用于小体积门锁,密码锁,柜锁,接下来介绍一下这款芯片的具体功能。优势1.超低功耗,最低功耗达1.7uA(MCU模块处于掉电模式,读卡器模块处于硬掉电模式);2.典型ACD模式功耗为4.1uA(MCU模块处于掉......
  • 26.高并发服务器
    26.高并发服务器阻塞函数在阻塞期间若收到信号,会被信号终端,errno设置为EINTR,这个错误不应该看成一个错误。while(1){ cfd=accept(); while(1) { n=read(cfd,buf,sizeof(buf)); if(n<=0) { break; } }}解决办法1:将cfd设置为非阻塞:fcntl假......
  • 力扣---1123. 最深叶节点的最近公共祖先
    给你一个有根节点 root 的二叉树,返回它 最深的叶节点的最近公共祖先 。回想一下:叶节点 是二叉树中没有子节点的节点树的根节点的 深度 为 0,如果某一节点的深度为 d,那它的子节点的深度就是 d+1如果我们假定 A 是一组节点 S 的 最近公共祖先,S 中的每个节点都在......
  • 【题解】CF2600DP 选练(23.9.5-23.9.6)
    低情商:感觉是比较套路的高情商:十分educational!!!CF258DLittleElephantandBrokenSorting题目描述:有一个\([1,n]\)的排列\(a\),会进行\(m\)次操作,操作为交换\((a_i,a_j)\)。每次操作都有\(50\%\)的概率进行。求进行\(m\)次操作以后的期望逆序对个数。\(n,m\le1......
  • 24V直流DC浪涌过压保护推荐26V电压TVS二极管
    直流DC电源端口浪涌过压防护一直都是很多新老电子工程师关注的方案之一。不管是电源端口浪涌防护还是信号接口静电保护,浪涌静电防护,找东沃,电路保护不迷路!东沃电子专注于研发、生产、销售静电保护二极管(ESD)、瞬态抑制二极管(TVS)、陶瓷气体放电管(GDT)、压敏电阻(MOV)、自恢复保险丝(PPTC)、......
  • 【Leetcode刷题记录】1、统计参与通信的服务器;2、统计二叉树中好节点的数目;3、从两个
    1、统计参与通信的服务器题目:这里有一幅服务器分布图,服务器的位置标识在 m*n 的整数矩阵网格 grid 中,1表示单元格上有服务器,0表示没有。如果两台服务器位于同一行或者同一列,我们就认为它们之间可以进行通信。请你统计并返回能够与至少一台其他服务器进行通信的服务器的......
  • 代码随想录算法训练营第十四天|二叉树的递归法、迭代法
    二叉树的递归遍历(前中后序遍历-递归法与迭代法)递归三部曲:确定递归函数的参数和返回值确定终止条件确定单层递归的逻辑递归法对二叉树进行前中后序遍历(力扣144.145.94.)//前序遍历·递归·LC144_二叉树的前序遍历classSolution{publicList<Integer>preorderTra......