剑指offer——JZ86 在二叉树中找到两个节点的最近公共祖先 解题思路与具体代码【C++】

一、题目描述与要求

在二叉树中找到两个节点的最近公共祖先_牛客题霸_牛客网 (nowcoder.com)

题目描述

给定一棵二叉树(保证非空)以及这棵树上的两个节点对应的val值 o1 和 o2,请找到 o1 和 o2 的最近公共祖先节点。

数据范围:树上节点数满足1≤n≤10的5次方  , 节点值val满足区间 [0,n)

要求:时间复杂度O(n)

注:本题保证二叉树中每个节点的val值均不相同。

如当输入{3,5,1,6,2,0,8,#,#,7,4},5,1时,二叉树{3,5,1,6,2,0,8,#,#,7,4}如下图所示:

所以节点值为5和节点值为1的节点的最近公共祖先节点的节点值为3,所以对应的输出为3。

节点本身可以视为自己的祖先

示例

示例1:

输入:{3,5,1,6,2,0,8,#,#,7,4},5,1

返回值:3

示例2:

输入:{3,5,1,6,2,0,8,#,#,7,4},2,7

返回值:2


二、解题思路

根据题目要求,我们需要找到二叉树中两个节点的最近公共祖先,与二叉搜索树不同的是二叉树中节点的排序是没有规律的,所以如果我们按照二叉搜索树的思路去解决这道题目的话,需要改变寻找路径的方法

对于二叉树我们想要找到从根节点到一个结点的路径,可以通过深度优先算法,也就是沿着根节点一直访问到叶子结点,同时在访问每个结点的时候判断其是否是所要找的结点并记录下路径,如果不是并且已经走到当前分支的最后,则回溯到上一个结点走下一条分支,直至将整个二叉树遍历完或者找到路径。

首先定义一个标志flag,用来判断是否找到对应路径,初始化为false,为全局变量;

接着定义存储两条路径的vector,然后就是调用dfs函数去寻找第一条路径;

找到第一条路径后重置标志为false,然后接着调用dfs函数去寻找第二条路径;

接着通过for循环来找到两条路径中最后一个相同的结点,返回结果即可。

dfs函数实现,首先判断是否已经找到路径或者访问到叶子结点,是的话直接返回上一级;

否则将当前结点存入路径,判断当前结点是否就是目标结点,是的话更新标志并返回,否则递归遍历当前结点的左右子树;

如果找完了当前结点的子树没有目标结点,则弹出,回溯父结点。


三、具体代码

#include <vector>
class Solution {
public:/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** * @param root TreeNode类 * @param o1 int整型 * @param o2 int整型 * @return int整型*/bool flag=false;//标志是否找到路径void dfs(TreeNode* root,vector<int>& path,int x){//如果已经找到路径或者访问到叶子结点则返回if(flag||root==nullptr) return;//将当前结点压入path.push_back(root->val);//如果找到目标结点,将标志设置为true,并返回if(root->val==x){flag=true;return;}//否则递归遍历结点的左右子树dfs(root->left,path,x);dfs(root->right,path,x);if(flag) return;//如果找到了则返回path.pop_back();//若当前子树没有,则回溯到父节点}int lowestCommonAncestor(TreeNode* root, int o1, int o2) {//获取根结点到两个结点的路径vector<int> path1,path2;dfs(root,path1,o1);flag=false;//找到一条路径后flag为true,需要重置,用于查找下一条路径dfs(root,path2,o2);int res=0;for(int i=0;i<path1.size()&&i<path2.size();i++){if(path1[i]==path2[i]) res=path1[i];else break;}return res;}
};

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

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

相关文章

UE5修改导航网格的参数

Unreal Engine 4 - Recast NavMesh Size, how to Change Agent Radius / Tutorial - YouTubehttps://www.youtube.com/watch?vf3hF6xdmCTk 修改当前的 代理半径就是一般贴边的长度 修改编辑器的

deckGL自定义图层学习笔记

1.自定义图层 当使用DeckGL提供的图层还无法满足需求时&#xff08;https://deck.gl/docs/api-reference/layers&#xff09;&#xff0c;可能就需要自定义图层了。在DeckGL中有常见的三种自定义图层的方式 创建复合层&#xff08;composite layers.&#xff09;——复合层是一…

建立数据科学基础设施的绝佳指南 数据工程师都该人手一册

《Effective数据科学基础设施》由Netflix工程师Ville Tuulos撰写&#xff0c;以Metaflow为对象&#xff0c;介绍了数据科学所需要的基础设施&#xff0c;囊括数据准备、特征工程、模型训练、模型部署、服务和持续监控等环节。Metaflow专注于构建生产流程&#xff0c;更适合具有…

最新AI创作系统源码ChatGPT网站源码V2.6.3/支持Midjourney绘画/支持OpenAI GPT全模型+国内AI全模型

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统&#xff0c;支持OpenAI GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作Chat…

想要开发一款游戏, 需要注意什么?

开发一款游戏是一个复杂而令人兴奋的过程。游戏开发是指创建、设计、制作和发布电子游戏的过程。它涵盖了从最初的概念和创意阶段到最终的游戏发布和维护阶段的各个方面。 以下是一些需要注意的关键事项&#xff1a; 游戏概念和目标&#xff1a; 确定游戏开发的核心概念和目标…

小视频APP源码选择指南:挑选最适合你的开发框架

在如今蓬勃发展的小视频APP行业中&#xff0c;源码的选择是打造一款成功应用的关键步骤。然而&#xff0c;面对众多开发框架的选择&#xff0c;如何挑选最适合你的小视频APP源码呢&#xff1f;作为这一领域的专家&#xff0c;我将为你提供一份详尽的指南&#xff0c;助你在源码…

nginx-proxy反向代理缓存

介绍&#xff1a; 反向代理缓存&#xff0c;类似于动静分离&#xff0c;即通过nginx代理服务器根据客户端发送的url请求&#xff0c;去后台服务器获取数据&#xff0c;将静态数据缓存到nginx代理服务器上&#xff0c;并配置有过期时间&#xff0c;当客户端下次以相同的url请求…

LVS+Keepalived 高可用集群负载均衡

一.keepalived介绍 1.1.Keepalived实现原理 由多台路由器组成一个热备组&#xff0c;通过共用的虚拟IP地址对外提供服务。 每个热备组内同时只有一台主路由器提供服务&#xff0c;其他路由器处于冗余状态。 若当前在线的路由器失效&#xff0c;则其他路由器会根据设置…

【Python查找算法】二分查找、线性查找、哈希查找

目录 1 二分查找算法 2 线性查找算法 3 哈希查找算法 1 二分查找算法 二分查找&#xff08;Binary Search&#xff09;是一种用于在有序数据集合中查找特定元素的高效算法。它的工作原理基于将数据集合分成两半&#xff0c;然后逐步缩小搜索范围&#xff0c;直到找到目标元素…

ChatGPT是如何产生心智的?

一、前言 - ChatGPT真的产生心智了吗&#xff1f; 来自斯坦福大学的最新研究结论&#xff0c;一经发出就造成了学术圈的轰动&#xff0c;“原本认为是人类独有的心智理论&#xff08;Theory of Mind&#xff0c;ToM&#xff09;&#xff0c;已经出现在ChatGPT背后的AI模型上”…

[极客大挑战 2020]Roamphp2-Myblog - 伪协议+文件上传+(LFIZIP)||(LFIPhar)【***】

[极客大挑战 2020]Roamphp2-Myblog 1 解题流程1.1 分析1.2 解题1.3 中场休息——再分析1.3.1 浅层分析1.3.2 难点疑惑1.3.3 深度分析 1.4 重整旗鼓——再战1.4.1 解法一&#xff1a;zip伪协议1.4.2 解法二&#xff1a;phar伪协议 2 总结展望 1 解题流程 1.1 分析 1、点击logi…

Linux——指令初识(二)

Linux下基本指令 前言一、时间相关的指令二、Cal指令三、find指令四、grep指令五、sort指令六、uniq指令七、.zip/unzip指令八、.tar指令九、uname –r指令十、重要的几个热键[Tab],[ctrl]-c, [ctrl]-d十一、关机总结 前言 linux的学习开始啦&#xff01; 今天我们继续来认识指…

零基础自学考证HCIE分享,附零基础HCIE学习路线

最近有些粉丝问我&#xff0c;能不能自学华为认证网络工程师HCIE&#xff1f; 我的回答是&#xff1a;能&#xff0c;但是很难。 据不完全统计&#xff0c;考上HCIE的人群中自学占比10%左右。为什么会这么低呢&#xff0c;下面就来给大家说考HCIE自学会遇到的一些困难。 首先&…

Android约束布局ConstraintLayout的Guideline,CardView

Android约束布局ConstraintLayout的Guideline&#xff0c;CardView <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:a…

【java学习】一维数组(9)

文章目录 1. 一维数组声明2. 一维数组初始化3. 数组元素的引用4. 数组元素的默认初始化 1. 一维数组声明 声明方式&#xff1a; type var[] 或 type[] var 例如&#xff1a; int a[]; int[] a1; double b[]; Mydate[] c; //对象数组2. 一维数组初始化 动态初始化&#xf…

VMware和别的服务器 ,组建局域网那些事 。

利用VMware &#xff0c;实现组件局域网、有可能会受限于WiFi&#xff08;路由器&#xff09; 。 通常不会&#xff0c;除非做了网关设置 相关知识&#xff1a; 禁用局域网隔离&#xff08;LAN Isolation&#xff09;&#xff1a; 某些路由器提供了一个选项&#xff0c;允许您禁…

【面试算法——动态规划 21】不同的子序列(hard) 通配符匹配(hard)

115. 不同的子序列 给你两个字符串 s 和 t &#xff0c;统计并返回在 s 的 子序列 中 t 出现的个数&#xff0c;结果需要对 109 7 取模。 链接&#xff1a;&#xff1a;https://leetcode.cn/problems/distinct-subsequences/ 示例 1&#xff1a; 输入&#xff1a;s “rab…

【微服务】八. 统一网关gateway

8.1 网关作用介绍 网关功能&#xff1a; 身份认证和权限校验服务路由、负载均衡请求限流 网关的技术实现 在SpringCloud中网关的实现包括两种&#xff1a; gatewayzuul Zuul是基于Servlet的实现&#xff0c;属于阻塞式编程。而SpringCloudGateway则是基于Spring5中提供的Web…

“元创新·智生成” 第15届企业数智化学习大会公布嘉宾阵容

2023年是AIGC爆发年&#xff0c;与AI相关的创新应用迅速向各行各业渗透。 在企业培训领域&#xff0c;数字人、元宇宙等正逐渐成为企业在开展人才发展、业务培训等工作的工具&#xff0c;其高效、便捷、在线化、场景化等优势受到企业的热捧。在需求的推动下&#xff0c;企业培…

springboot整合pi支付开发

pi支付流程图&#xff1a; 使用Pi SDK功能发起支付由 Pi SDK 自动调用的回调函数&#xff08;让您的应用服务器知道它需要发出批准 API 请求&#xff09;从您的应用程序服务器到 Pi 服务器的 API 请求以批准付款&#xff08;让 Pi 服务器知道您知道此付款&#xff09;Pi浏览器向…