注:本文的代码实现使用的是 JS(JavaScript),为前端中想使用JS练习算法和数据结构的小伙伴提供解题思路。(

描述

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

最近公共祖先的定义为:“对于有根树 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 为不同节点且均存在于给定的二叉搜索树中。

解题思路

1. 两次遍历法

我们可以两个数组p_pathq_path分别记录从根节点到pq的路径,然后从两个路径中找到最后一个相同的节点即可。因此,只要找出最大的编号i,其满足:
p_path[i]=q_path[i]p\_path[i] = q\_path[i]p_path[i]=q_path[i]
由于题目给定的是搜索二叉树,可以利用其性质,优化搜索过程。

var lowestCommonAncestor = function(root, p, q) {// 查找路径函数,root是原始的树,node是需要查找的节点let find = (root, node) => {// 定义路径数组let path = []while(root){path.push(root)// 根节点的值小于查找节点的值,则遍历右子树if(root.val < node.val) root = root.right// 根节点的值大于查找节点的值,则遍历左子树else if(root.val > node.val) root = root.left// 找到需要查找的节点,返回路径else return path}}let p_path = find(root, p)let q_path = find(root, q)// 定义祖先变量let ancestor = null// 只需要在最短的路径中查找即可let len = Math.min(p_path.length, q_path.length)// 比较两个路径,若节点相同,则将 ancestor 指向该节点for(let i = 0; i < len; i++)// 只要节点相同,ancestor 就会更新,因此 ancestor 保存的是最后一次相同的节点if(p_path[i] === q_path[i]) ancestor = p_path[i]return ancestor
};

2. 一次遍历法

我们还可以简化上面的方法。

  • 若节点pq的值均大于当前根节点的值,说明节点pq的祖先一定在当前节点的右子树上
  • 若节点pq的值均小于当前根节点的值,说明节点pq的祖先一定在当前节点的左子树上
  • 如果当前节点的值不满足上述两条要求,那么说明当前节点就是「分岔点」,即最近公共祖先
var lowestCommonAncestor = function(root, p, q) {while(true){if(root.val < p.val && root.val < q.val) root = root.rightelse if(root.val > p.val && root.val > q.val) root = root.leftelse return root}
};

力扣题目——235. 二叉搜索树的最近公共祖先相关推荐

  1. ( “树” 之 BST) 235. 二叉搜索树的最近公共祖先 ——【Leetcode每日一题】

    二叉查找树(BST):根节点大于等于左子树所有节点,小于等于右子树所有节点. 二叉查找树中序遍历有序. 235. 二叉搜索树的最近公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. ...

  2. leetcode 235. 二叉搜索树的最近公共祖先(Java版,树形dp套路)

    题目 原题地址:leetcode 235. 二叉搜索树的最近公共祖先 说明: 所有节点的值都是唯一的. p.q 为不同节点且均存在于给定的二叉搜索树中. 题解 关于 树形dp 套路,可以参考我的另一篇 ...

  3. 二叉树part8 | ● 235. 二叉搜索树的最近公共祖先 ● 701.二叉搜索树中的插入操作 ● 450.删除二叉搜索树中的节点

    文章目录 235. 二叉搜索树的最近公共祖先 思路 代码 困难 701.二叉搜索树中的插入操作 思路 代码 450.删除二叉搜索树中的节点 思路 代码 困难 今日收获 235. 二叉搜索树的最近公共祖 ...

  4. Leetcode 235.二叉搜索树的最近公共祖先

    Time: 20190907 Type: Easy 题目描述 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p. ...

  5. leetcode —— 235. 二叉搜索树的最近公共祖先

    给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结点 x,满足 x 是 p.q 的祖 ...

  6. 【C语言刷LeetCode】235. 二叉搜索树的最近公共祖先(E)

    [ 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结点 x,满足 x 是 p.q ...

  7. leetcode 235. 二叉搜索树的最近公共祖先 思考分析

    目录 题目 思考 迭代法 题目 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结点 ...

  8. LeetCode 235. 二叉搜索树的最近公共祖先(递归)

    题目描述 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结点 x,满足 x 是 p ...

  9. 最近公共祖先 python_?235. 二叉搜索树的最近公共祖先(Python)

    题目 难度:★★☆☆☆ 类型:二叉树 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q,最近公共祖先表示为一 ...

最新文章

  1. SQL Server 2005 XML 操作总结(七)属性操作——插入、修改操作
  2. JSP页面最终是编译为Servlet执行的
  3. 查看表扫描次数,并对比索引对表查询的作用
  4. 【Linux命令】nm 查看动态库和静态库中的符号
  5. 怎么在ASP.NET 2.0中使用Membership (转载)
  6. sdut3138: N!(计算n!中结尾零的个数)
  7. Appium实现的技巧
  8. 2017华为软件精英挑战赛思路分析
  9. Suricata默认规则集相关
  10. 计算机基础知识试题及答案填空题,计算机基础知识练习题及答案解析
  11. 2020.01.18【NOIP提高组】模拟B 组——总结——探险者拉罗
  12. ubuntu安装无线网卡驱动(Ralink)
  13. android微信朋友圈相册背景,微信朋友圈相册背景多大尺寸合适
  14. 买iPhone担心买到翻新机?教你一招,轻松鉴别各个版本
  15. 用python做头像_教你用python下载和拼接微信好友头像图片
  16. 线性代数:行列法则Python计算AB矩阵乘法
  17. SpringDataJPA+Hibernate框架源码剖析(六)@PersistenceContext和@Autowired注入EntityManager的区别
  18. 易语言游戏辅助开发原理分析
  19. 如何保证路缘石滑模机作业质量的几个原则
  20. Java 下载zip文件

热门文章

  1. 社交网络中各类产品形态的分析
  2. WIZnet无线模块WizFi210/220 硬件设计指导
  3. Build DCM4chee2
  4. enspar启动失败40_适合烘焙新手第一次做的芝士面包,简单易上手,好吃松软零失败...
  5. 5G:无人驾驶的“超级英雄”路
  6. 流程DEMO-费用报销
  7. asm数据文件迁移(os–asm)
  8. 各种开源Android 系统定制
  9. Binary XML file line #27: Error inflating class Listview
  10. DHCP服务器控制企业成本