68 - I. 二叉搜索树的最近公共祖先


comments: true
difficulty: 简单
edit_url: https://github.com/doocs/leetcode/edit/main/lcof/%E9%9D%A2%E8%AF%95%E9%A2%9868%20-%20I.%20%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E7%9A%84%E6%9C%80%E8%BF%91%E5%85%AC%E5%85%B1%E7%A5%96%E5%85%88/README.md

面试题 68 - I. 二叉搜索树的最近公共祖先

题目描述

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

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

例如,给定如下二叉搜索树:  root = [6,2,8,0,4,7,9,null,null,3,5]

 

示例 1:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6 
解释: 节点 2 和节点 8 的最近公共祖先是 6。

示例 2:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。

 

说明:

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

注意:本题与主站 235 题相同:https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree/

解法

方法一:一次遍历

从上到下遍历二叉树,找到第一个值位于 [ p . v a l , . . q . v a l ] [p.val,.. q.val] [p.val,..q.val] 之间的结点即可【核心】。既可以用迭代实现,也可以用递归实现。

时间复杂度 O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。空间复杂度方面,迭代实现的空间复杂度为 O ( 1 ) O(1) O(1),递归实现的空间复杂度为 O ( n ) O(n) O(n)

Python3
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = Noneclass Solution:def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:while 1:if root.val < p.val and root.val < q.val:   # 说明p,q节点在右子树,因此公共祖先节点也应该向右边找root = root.rightelif root.val > p.val and root.val > q.val: # 反之,亦然root = root.leftelse:return root
Java
/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {while (true) {if (root.val < p.val && root.val < q.val) {root = root.right;} else if (root.val > p.val && root.val > q.val) {root = root.left;} else {return root;}}}
}
C++
/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/
class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if (root->val < p->val && root->val < q->val) {return lowestCommonAncestor(root->right, p, q);}if (root->val > p->val && root->val > q->val) {return lowestCommonAncestor(root->left, p, q);}return root;}
};
Go
/*** Definition for a binary tree node.* type TreeNode struct {*     Val   int*     Left  *TreeNode*     Right *TreeNode* }*/func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {if root.Val < p.Val && root.Val < q.Val {return lowestCommonAncestor(root.Right, p, q)}if root.Val > p.Val && root.Val > q.Val {return lowestCommonAncestor(root.Left, p, q)}return root
}
TypeScript
/*** Definition for a binary tree node.* class TreeNode {*     val: number*     left: TreeNode | null*     right: TreeNode | null*     constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {*         this.val = (val===undefined ? 0 : val)*         this.left = (left===undefined ? null : left)*         this.right = (right===undefined ? null : right)*     }* }*/
function lowestCommonAncestor(root: TreeNode | null,p: TreeNode | null,q: TreeNode | null,
): TreeNode | null {if (root == null) {return root;}if (root.val > p.val && root.val > q.val) {return lowestCommonAncestor(root.left, p, q);}if (root.val < p.val && root.val < q.val) {return lowestCommonAncestor(root.right, p, q);}return root;
}
Rust
// Definition for a binary tree node.
// #[derive(Debug, PartialEq, Eq)]
// pub struct TreeNode {
//   pub val: i32,
//   pub left: Option<Rc<RefCell<TreeNode>>>,
//   pub right: Option<Rc<RefCell<TreeNode>>>,
// }
//
// impl TreeNode {
//   #[inline]
//   pub fn new(val: i32) -> Self {
//     TreeNode {
//       val,
//       left: None,
//       right: None
//     }
//   }
// }
use std::cell::RefCell;
use std::cmp::Ordering;
use std::rc::Rc;
impl Solution {pub fn lowest_common_ancestor(mut root: Option<Rc<RefCell<TreeNode>>>,p: Option<Rc<RefCell<TreeNode>>>,q: Option<Rc<RefCell<TreeNode>>>,) -> Option<Rc<RefCell<TreeNode>>> {let p = p.unwrap().borrow().val;let q = q.unwrap().borrow().val;loop {let mut cur = root.as_ref().unwrap().borrow().val;match (cur.cmp(&p), cur.cmp(&q)) {(Ordering::Less, Ordering::Less) => {root = root.unwrap().borrow().right.clone();}(Ordering::Greater, Ordering::Greater) => {root = root.unwrap().borrow().left.clone();}(_, _) => {break root;}}}}
}
JavaScript
/*** Definition for a binary tree node.* function TreeNode(val) {*     this.val = val;*     this.left = this.right = null;* }*/
/*** @param {TreeNode} root* @param {TreeNode} p* @param {TreeNode} q* @return {TreeNode}*/
var lowestCommonAncestor = function (root, p, q) {if (root.val < p.val && root.val < q.val) {return lowestCommonAncestor(root.right, p, q);} else if (root.val > p.val && root.val > q.val) {return lowestCommonAncestor(root.left, p, q);}return root;
};

方法二:递归

Python3
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = Noneclass Solution:def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':if root.val < p.val and root.val < q.val:return self.lowestCommonAncestor(root.right, p, q)if root.val > p.val and root.val > q.val:return self.lowestCommonAncestor(root.left, p, q)return root
Java
/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if (root.val < p.val && root.val < q.val) {return lowestCommonAncestor(root.right, p, q);}if (root.val > p.val && root.val > q.val) {return lowestCommonAncestor(root.left, p, q);}return root;}
}
C++
/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/
class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {while (1) {if (root->val < p->val && root->val < q->val) {root = root->right;} else if (root->val > p->val && root->val > q->val) {root = root->left;} else {return root;}}}
};
Go
/*** Definition for a binary tree node.* type TreeNode struct {*     Val   int*     Left  *TreeNode*     Right *TreeNode* }*/func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {for {if root.Val < p.Val && root.Val < q.Val {root = root.Right} else if root.Val > p.Val && root.Val > q.Val {root = root.Left} else {return root}}
}
TypeScript
/*** Definition for a binary tree node.* class TreeNode {*     val: number*     left: TreeNode | null*     right: TreeNode | null*     constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {*         this.val = (val===undefined ? 0 : val)*         this.left = (left===undefined ? null : left)*         this.right = (right===undefined ? null : right)*     }* }*/
function lowestCommonAncestor(root: TreeNode | null,p: TreeNode | null,q: TreeNode | null,
): TreeNode | null {if (root == null) {return root;}while (true) {if (root.val > p.val && root.val > q.val) {root = root.left;} else if (root.val < p.val && root.val < q.val) {root = root.right;} else {return root;}}
}
Swift
/*** Definition for a binary tree node.* public class TreeNode {*     public var val: Int*     public var left: TreeNode?*     public var right: TreeNode?*     public init(_ val: Int) {*         self.val = val*         self.left = nil*         self.right = nil*     }* }*/class Solution {func lowestCommonAncestor(_ root: TreeNode?, _ p: TreeNode?, _ q: TreeNode?) -> TreeNode? {guard let p = p, let q = q else {return nil}var node = rootwhile let current = node {if current.val < p.val && current.val < q.val {node = current.right} else if current.val > p.val && current.val > q.val {node = current.left} else {return current}}return nil}
}

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

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

相关文章

MySQL高阶1873-计算特殊奖金

目录 题目 准备数据 分析数据 总结 题目 编写解决方案&#xff0c;计算每个雇员的奖金。如果一个雇员的 id 是 奇数 并且他的名字不是以 M 开头&#xff0c;那么他的奖金是他工资的 100% &#xff0c;否则奖金为 0 。 返回的结果按照 employee_id 排序。 准备数据 Crea…

【Python语言初识(一)】

一、python简史 1.1、python的历史 1989年圣诞节&#xff1a;Guido von Rossum开始写Python语言的编译器。1991年2月&#xff1a;第一个Python编译器&#xff08;同时也是解释器&#xff09;诞生&#xff0c;它是用C语言实现的&#xff08;后面&#xff09;&#xff0c;可以调…

Python编码系列—Python代理模式:为对象赋予超能力的魔法

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

数据结构(Day14)

一、学习内容 结构体 概念 引入&#xff1a;定义整数赋值为10 int a10; 定义小数赋值为3.14 float b3.14; 定义5个整数并赋值 int arr[5] {1 , 2 , 3 , 4 ,5}; 定义一个学生并赋值学号姓名成绩 定义一个雪糕并赋值名称产地单价 问题&#xff1a;没有学生、雪糕 数据类型 解决&…

Python语言学习-pandas库学习

一、什么是Pandas库 Pandas是python的第三方库&#xff0c;他用于灵活的数据操作&#xff0c;数据可视化&#xff0c;数据清洗&#xff0c;数据的聚合和转换&#xff0c;数据的可视化 二、安装pandas库 在终端中运行 pip install pandas 导入Pandas库并重命名为pd import …

2024年9月第3周AI资讯

阅读时间&#xff1a;3-4min 更新时间&#xff1a;2024.9.16-2024.9.20 目录 OpenAI 推出 o1&#xff1a;一种新的“推理”人工智能模型 微软为 Excel 和 Word 添加了更快的 Copilot World Labs 利用 AI 创建 3D 世界 AI 利用文本创建开放世界视频游戏 OpenAI 推出 o1&#x…

【vue element-ui】关于删除按钮的提示框,可一键复制

实现效果&#xff1a; Delete: function (id) {this.$confirm(此操作将永久删除该文件, 是否继续?, 提示, {confirmButtonText: 确定,cancelButtonText: 取消,type: warning,center: true,}).then(() > {Delete(id).then(() > {this.$message({type: success,message: 删…

工业交换机如何保证数据的访问安全

在现代工业自动化环境中&#xff0c;工业交换机作为关键的网络设备&#xff0c;扮演着数据传输和信息交互的重要角色。为了确保数据的访问安全&#xff0c;工业交换机不仅具备高效的转发性能&#xff0c;还集成了多层次的安全防护机制&#xff0c;以抵御各种潜在的网络威胁。 首…

传输大咖44 | 云计算企业大数据迁移如何更安全高效?

在云计算时代&#xff0c;数据已成为企业最宝贵的资产之一。对于依赖云服务的企业和组织来说&#xff0c;大数据迁移是实现业务扩展和优化的关键步骤。然而&#xff0c;这一过程并非没有挑战。传统的文件传输方式在安全性、稳定性和速度上往往无法满足云计算企业的需求。本文将…

C++(Qt)软件调试---断点高级用法(20)

C(Qt)软件调试—断点高级用法&#xff08;20&#xff09; 文章目录 C(Qt)软件调试---断点高级用法&#xff08;20&#xff09;[toc]1、概述2、断点高级用法1.1 条件断点1.2 日志断点/记录点/消息追踪点1.3 函数断点1.4 命中次数断点1.5 异常断点1.6 等待断点/触发断点1.7 临时断…

掌握数据中心虚拟化:关键挑战与解决方案

数据中心虚拟化是使用云软件平台将物理数据中心转变为数字数据中心的过程&#xff0c;使企业能够远程访问信息和应用程序。它包括在数据中心内创建物理基础设施的多个虚拟版本&#xff0c;通过将服务器、存储和网络等资源划分为虚拟实体来实现资源的高效利用。 虚拟化环境中的关…

Tomcat CVE-2017-12615 靶场攻略

漏洞描述 当 Tomcat运⾏在Windows操作系统时&#xff0c;且启⽤了HTTP PUT请求⽅法&#xff08;例如&#xff0c;将 readonly初始化参数由默认值设置为false&#xff09;&#xff0c;攻击者将有可能可通过精⼼构造的攻击请求数据包向服务器上传包含任意代 的 JSP ⽂件&#xf…

MySQL —— 索引

索引的概念 MySQL的索引是⼀种数据结构&#xff0c;它可以帮助数据库高效地查询、更新数据表中的数据。索引通过 ⼀定的规则排列数据表中的记录&#xff0c;使得对表的查询可以通过对索引的搜索来加快速度。 MySQL索引类似于书籍的目录&#xff0c;通过指向数据行的位置&…

Docker + Win 10 学习记录

下载Docker Release notes | Docker Docs 推荐使用4.33版本&#xff0c;最新的Docker版本在win10 22H2无法安装。需要升级到win11. 查看Win10版本是否与最新版的Docker兼容 运行 win R&#xff0c; 然后输入winver 如果你的Docker版本无法在当前的win10安装&#xff0c;请更…

基于云计算的虚拟电厂负荷预测

基于云计算的虚拟电厂负荷预测 随着电网规模的扩大及新能源的不断应用&#xff0c;并网电网的安全性和经济性备受关注。 电网调度不再是单一或局部控制&#xff0c;而是采用智能网络集成方式调度 。 智能电网应具有以下特点&#xff1a;坚强自愈&#xff0c;可以抵御外来干扰甚…

如何删除EXCELL文件中的空行?

1&#xff0c;选择某一列 2&#xff0c;点击《开始》《查找和选择》>《定位条件》&#xff0c;调出《定位条件》的选择框&#xff1b; 3&#xff0c;在定位条件选项框&#xff0c;选择《空值》&#xff1b; 4&#xff0c;找到变灰被选中的某一行&#xff0c;右击《删除》 5&…

Qt 构建版本

Qt提供了三种不同的构建版本&#xff1a;Debug版本&#xff08;调试版本&#xff09;、Release版本&#xff08;发布版本&#xff09;和Profile版本&#xff08;概述版本&#xff09;&#xff0c;每种版本都有其特定的用途和编译设置。 Debug版本&#xff08;调试版本&#x…

基于 SpringBoot 的在线考试系统

专业团队&#xff0c;咨询就送开题报告&#xff0c;欢迎大家私信留言&#xff0c;联系方式在文章底部 摘 要 网络的广泛应用给生活带来了十分的便利。所以把在线考试管理与现在网络相结合&#xff0c;利用java技术建设在线考试系统&#xff0c;实现在线考试的信息化管理。则对…

Python类及元类的创建流程

Python类及元类的创建流程 代码运行结果再看type和object的关系和约定type和object具有的方法不一样看代码和运行结果&#xff0c;可以完全理解python的执行过程。再补充几点&#xff0c; 代码 class MetaCls(type):print(0>>>, MetaCls, 0)def __init__(self, name,…

uniapp vue3 梯形选项卡组件

实现的效果图&#xff1a; 切换选项卡显示不同的内容&#xff0c;把这个选项卡做成了一个组件&#xff0c;需要的自取。 // 组件名为 trapezoidalTab <template> <view class"pd24"><view class"nav"><!-- 左侧 --><view cla…