力扣236. 二叉树的最近公共祖先(java DFS解法)

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

文章目录

  • 题目描述
  • 思路
  • 解题方法
  • 复杂度
  • Code

题目描述

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

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

在这里插入图片描述

思路

首先我们要注意到题目所给提示**二叉树的所有节点值均不相等!!!**在此基础上我们可以得到二叉树的最近公共祖先唯一存在如下两种情况:

1.若当前节点的左子树和右子树均存在给定节点的其一,则当前节点为最近公共祖先;
2.若当前节点等于所给节点的其中一个,同时当前节点的左子树或者右子树中存在所给节点的另一个节点,则当前节点为最近公共祖先

如下图示:
image.png
image.png

解题方法

1.定义一个TreeNode类型的指针命名为location用于记录并返回最后的最近公共祖先
2.递归后续遍历二叉树,记录当前节点(包括当前节点)的左子树或右子树节点等于给定节点的个数
3.判断当前节点是否等于给定节点中其一,同时其左右子树中等于给定节点的个数(具体的判定条件看思路)判定成立时将指针location指向当前节点。
4.注意若在递归过程中发现指针location已经不为null则直接退出递归

复杂度

时间复杂度:

O ( n ) O(n) O(n)

空间复杂度:

O ( n ) O(n) O(n)

Code

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Solution {//用于记录指定节点最近的父节点位置private TreeNode location = null;/*** 求取二叉树中指定两节点的最近公共父节点(二叉树任意节点值无重复)** @param root 树的根节点* @param p    指定节点p* @param q    指定节点q* @return TreeNode*/public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {depthFirstSearch(root, p, q);return location;}/*** 深度优先(此处为二叉树的后序遍历)求取某一节点指定的* 节点p 与 q的个数,利用其找到最近父节点的位置* @param root 树的根节点* @param p    指定节点p* @param q    指定节点q* @return int*/private int depthFirstSearch(TreeNode root, TreeNode p, TreeNode q) {if (root == null) {return 0;}//当前节点左子树包含p,q节点的个数int leftContains = depthFirstSearch(root.left, p, q);//当已经找到location时提前退出if (location != null) {return 2;}//当前节点右子树包含p,q节点的个数int rightContains = depthFirstSearch(root.right, p, q);if (location != null) {return 2;}//记录当前节点值等于q或pint rootContain = 0;//如果当前节点值等于p,q其一if (root == p || root == q) {rootContain = 1;}/*找到情况1:当当前节点值等于p,q其一时,同时当前节点的左子树或右子树包含q,p的个数为1找到情况2:当当前节点的左子树包含一个p或q其一,同时当前节点的右子树包含一个q或p其一*/if (rootContain == 1 && (leftContains == 1 || rightContains == 1)) {location = root;}if (rootContain == 0 && leftContains == 1 && rightContains == 1) {location = root;}return leftContains + rightContains + rootContain;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/165260.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android逆向一-frida操作

系列文章目录 第一章 frida操作 文章目录 系列文章目录前言一、两种模式二、frida命令行执行及参数三、frida使用python执行四、动静态域调用1. 静态域调用2.动态域调用 五. 远程rpc调用六. 补充总结 前言 熟悉frida操作,hook手机app的关键位置进行逆向操作 一、…

芯知识 | Flash可更换声音语音芯片—引领音频IC技术革新的新篇章

随着科技的飞速发展,人们对于电子产品的音频性能要求越来越高。在这种背景下,Flash可更换声音语音芯片应运而生,成为音频技术领域的一颗璀璨明星。本文将详细介绍Flash可更换声音语音芯片的特点、优势以及应用场景,展望其在未来科…

【Docker】从零开始:10.registry搭建私有仓库

【Docker】从零开始:10.registry搭建私有仓库 为什么要使用私有仓库关于Docker Registry基于容器搭建registry私有仓库1.下载镜像2. 启动镜像3.修改系统配置文件4.下载ubuntu镜像,修改名称3.提交镜像4.查看镜像 本地搭建私有仓库(目前编译报错找不到包&a…

【管理运筹学】背诵手册(五)| 动态规划

五、动态规划 基本概念 阶段(Stage):将所给问题的过程,按时间或空间特征分解成若干相互联系的阶段,以便按次序去求解每阶段的解,常用字母 k k k 表示。 状态(State):…

java实现连接linux(上传文件,执行shell命令等)

1 导入pom <dependency><groupId>com.jcraft</groupId><artifactId>jsch</artifactId><version>0.1.55</version></dependency> 2 编写配置类 package com.budwk.app.atest;import com.budwk.app.common.config.AppExceptio…

计算机网络之网络层

一、概述 主要任务是实现网络互连&#xff0c;进而实现数据包在各网络之间的传输 1.1网络引入的目的 从7层结构上看&#xff0c;网络层下是数据链路层 从4层结构上看&#xff0c;网络层下面是网络接口层 至少我们看到的网络层下面是以太网 以太网解决了什么问题&#xff1f; 答…

【Python 千题 —— 基础篇】删除列表值

题目描述 题目描述 删除列表的指定值。有一个列表 [1, 3, 5, 2, 44, 1, 9, 10, 32] &#xff0c;请使用 for 循环删除该列表中与 [44, 1, 9] 列表相同的值&#xff0c;并输出该列表。 输入描述 无输入。 输出描述 输出操作后的列表。 示例 示例 ① 输出&#xff1a; …

记录:通过day.js获取两个日期相差的时间,并转化为年月日的格式

day.js这个日期库真的是很不错的日期库&#xff0c;足够满足日常的开发需求。 Day.js中文网 (fenxianglu.cn) 需求&#xff1a;获取两个日期相差的时间&#xff0c;转化为年月日的形式&#xff1b;话不多少&#xff0c;直接放代码 import dayjs from "dayjs"; imp…

计算机网络之应用层

一、概述 引入目的&#xff1a; 为了方便用户去使用&#xff1b; 该如何方便用户使用网络呢&#xff0c;即怎样帮助用户使用网络&#xff1f; 1.用户需要知道网络资源所在的位置 2.网络上资源一定是在资源子网的主机上 3.资源子网上的主机&#xff0c;在通信子网中用IP地…

qt-C++笔记之终端Ctrl+C关闭界面和ROS节点

qt-C笔记之终端CtrlC关闭界面和ROS节点 code review! 文章目录 qt-C笔记之终端CtrlC关闭界面和ROS节点1.运行2.main.cpp3.main_window.hpp 1.运行 2.main.cpp 3.main_window.hpp

vue-router 路由权限,路由导航守卫

addRouter() 添加路由 使用场景 列如&#xff1a;菜单权限的分配&#xff08;管理员与用户不一致&#xff09; 根据后台返回 参数 定义isAdmin根据isAdmin 分配 let isAdmin true // 添加路由 可以传参 一级路由名称 来添加二级路由 if (isAdmin) {router.addRoute({path: /…

SpringCloud 微服务全栈体系(十六)

第十一章 分布式搜索引擎 elasticsearch 六、DSL 查询文档 elasticsearch 的查询依然是基于 JSON 风格的 DSL 来实现的。 1. DSL 查询分类 Elasticsearch 提供了基于 JSON 的 DSL&#xff08;Domain Specific Language&#xff09;来定义查询。常见的查询类型包括&#xff1…

P1030 [NOIP2001 普及组] 求先序排列

1.先找根&#xff08;后序最后一个元素&#xff09; 2.以根分中序为两个中序即&#xff1a; (相当于分为两个子树) A中序 对应->A后序 &#xff08;长度对应&#xff09; B中序 对应->B后序 &#xff08;长度对应&#xff09; 递归循坏即可&#xff08;中序长度小…

【数据结构(C语言)】浅谈栈和队列

目录 文章目录 前言 一、栈 1.1 栈的概念及结构 1.2 栈的实现 1.2.1. 支持动态增长的栈的结构 1.2.2 初始化栈 1.2.3 入栈 1.2.4 出栈 1.2.5 获取栈顶元素 1.2.6 获取栈中有效元素个数 1.2.7 检查栈是否为空 1.2.8 销毁栈 二、队列 2.1 队列的概念及结构 2.2 队…

Javaweb之前后台分离开发介绍的详细解析

2.1 前后台分离开发介绍 在之前的课程中&#xff0c;我们介绍过&#xff0c;前端开发有2种方式&#xff1a;前后台混合开发和前后台分离开发。 前后台混合开发&#xff0c;顾名思义就是前台后台代码混在一起开发&#xff0c;如下图所示&#xff1a; 这种开发模式有如下缺点&a…

守护进程的理解

什么是守护进程 daemon False # 是否以守护进程方式运行&#xff0c;True守护&#xff0c;False 非守护 在这段代码中&#xff0c;daemon 变量的值决定了进程是否以守护进程方式运行。如果 daemon 的值为 True&#xff0c;则表示进程将以守护进程方式运行&#xff0c;否则为…

使用vcpkg安装库失败的解决方法

1、前言 vcpk是是一款开源的c/c库管理工具&#xff0c;尤其是在windows平台&#xff0c;可以帮助我们很好的管理各种依赖包。 在windows环境做c/c开发的人应该都深有体会&#xff0c;有时候编译需要下载一堆依赖库&#xff0c;导致搭建编译环境特别麻烦。但是&#xff0c;通过v…

前端 vue 面试题(二)

文章目录 如何让vue页面重新渲染组件间通信vue为什么要mutation、 action操作插槽、具名插槽、作用域插槽vue编译使用的是什么库&#xff1f;vue怎么实现treeshakingwebpack实现treeshaking为什么只有es module 能支持 tree shaking mixin 的作用mixin的底层原理nexTick原理vue…

预处理机制

跟着肯哥&#xff08;不是我&#xff09;学预处理机制 预处理类别 宏定义&#xff1a;#define 将文本替换为表达式或语句 条件编译&#xff1a;#ifdef、#ifndef和#if、#elif、#endif 根据标识符是否被定义选择编译代码 头文件包含&#xff1a;#include 将其他文件&#x…

Jmeter怎么实现接口关联?

用于接口测试时&#xff0c;后一个接口经常需要用到前一次接口返回的结果&#xff0c;应该如何获取前一次请求的结果值&#xff0c;应用于后一个接口呢&#xff0c;拿一个登录的例子来说明如何获取。 1、打开jmeter&#xff0c;新建一个测试计划&#xff0c;在测试计划里新建一…