Solution1:我的答案

【针对阉割版的题目的偷鸡摸狗的做法】注意:书中的原题要更复杂一些,在牛客网中二叉树被设置为满二叉树且结点值从1开始,依次加1。

class LCA {
public:int getLCA(int a, int b) { //看来是一个数学推理题。。。// write code hereif (a == b)return a;int A = a, B = b;while (A != B) {if (A > B)A /= 2;else if (A < B)B /= 2;}return A;}
};

Solution2:正经做法

问题:找出二叉树中某两个结点的第一个公共祖先。
参考网址:
[1]https://blog.csdn.net/qinzhenhua100/article/details/64528136
[2]https://blog.csdn.net/xyzbaihaiping/article/details/52122885
题目分析:

假设1:这个二叉树是二叉排序树(O(N))

如果题目中的二叉树是二叉排序树,那么这道题目变的相对简单很多,我们只需要从根节点开始遍历,有以下三种情况发生:
(1)如果题目给的两个节点的值都大于当前节点,那么继续遍历当前节点的右子树
(2)如果题目给的两个节点的值都小于当前节点,那么继续遍历当前节点的左子树
(3)如果当前节点大于其中一个节点而小于其中另外一个节点,那么则返回该节点,该节点便是两个节点的公共祖先节点。

假设2:这个二叉树是普通的二叉树,但是存在指向父节点的指针

由于每个节点存在指向父节点的指针,所以如果给定任意一个节点,便可以找到从该节点到根节点的路径,因此我们可以找到题目中给予的两个节点分别到根节点的路径,因此该题目便变成了求两个单向链表的第一个公共节点。
假设2延伸:求两个单向链表第一个公共节点有两种方法:
(1)第一种方法是:两个链表如果有 公共节点,那么从第一个公共节点开始往后的所有节点都相同,我们首先遍历两个链表,求出两个链表的长度。然后设定两个指针分别指向这两个单向链表的头结 点,首先让链表较长的指针先移动,直至移动的剩余长度与链表较短的那个链表长度相同为止,这个时候两个指针开始同时移动,直到两个指针指向的节点相同,这 个节点便是这两个单向链表的第一个公共节点。
(2)第二种方法是:可以设置两个栈,首先分别把两个链表中的节点依次入栈,接下来从两个栈中同时一个一个的将节点弹出,遇到第一对弹出的节点不同时,那么前一次弹出相同的节点便是这两个链表的第一个公共节点。

【重点】假设3:这个二叉树是普通的二叉树,并且不存在指向父节点的指针

<方法1>:判断子树中是否存在某节点(时间复杂度O(N2)O(N^2)O(N2))

首先建立一个方法判断一棵树中是否存在某个节点,这个比较简单,只需要遍历整棵树,如果存在返回true,如果不存在则返回false。
接下来的判断过程就相当于二叉排序数的判断过程了,只不过二叉排序树判断一个节点是否在左子树或者右子树中只需要和父节点比较,而普通的树需要遍历整个左子树或者右子树才能实现。
(1)如果题目给的两个节点都在右子树,那么继续遍历当前节点的右子树
(2)如果题目给的两个节点都在左子树,那么继续遍历当前节点的左子树
(3)如果给定的两个节点一个在左子树,一个在右子树,则返回当前节点。

<方法2>:寻找从根节点到子节点的路径

如果找到从根节点到两个子节点的路径,那么题目就迎刃而解了,可以用栈遍历二叉树,最后找到从根节点到相应节点的路径,类似二叉树的先序非递归遍历一样,先遍历根节点,接着遍历左子树,接着遍历右子树,直到遍历到相应节点为止,这时栈中的元素便是路径元素。

<方法3>:递归遍历

设根节点为root,两个节点分别为p,q,用前序遍历方法递归遍历整个二叉树,如果只找到p则返回p,如果只找到q则返回q,如果一个节点的左右子树分别找到p,q,则返回该节点,其他情况返回NULL。
方法1的代码如下:

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/
class LCA {
public:TreeNode *commonAncestor(TreeNode *root, TreeNode *p, TreeNode *q) {if (!covers(root, p) || !covers(root, q))return null;return commonAncestorHelper(root, p, q);}bool covers(TreeNode *root, TreeNode *p) {if (!root) return NULL;if (root == p) return true;return covers(root->left, p) || covers(root->right, q);}TreeNode *commonAncestorHelper(TreeNode *root, TreeNode *p, TreeNode *q) {if (!root) return NULL;if (root == p || root == q) return root;bool is_p_in_left = covers(root->left, p);bool is_q_in_right = covers(root->right, q);//若p和q不在同一边则返回rootif (is_p_in_left != is_q_in_right) return root;//否则p和q在同一边,递归访问那一边TreeNode *tmp = is_p_in_left? root->left : root->right;return commonAncestorHelper(tmp, p, q);}};

程序员面试金典——4.7最近公共祖先相关推荐

  1. 最近公共祖先 牛客网 程序员面试金典 C++ Python

    最近公共祖先 牛客网 程序员面试金典 C++ Python 题目描述 有一棵无穷大的满二叉树,其结点按根结点一层一层地从左往右依次编号,根结点编号为1.现在有两个结点a,b.请设计一个算法,求出a和b ...

  2. 程序员面试金典--第k个数

    程序员面试金典--第k个数 题目描述 有一些数的素因子只有3.5.7,请设计一个算法,找出其中的第k个数. 给定一个数int k,请返回第k个数.保证k小于等于100. 测试样例: 3 返回:7 逐个 ...

  3. 程序员面试金典 - 面试题 08.13. 堆箱子(DP)

    1. 题目 堆箱子.给你一堆n个箱子,箱子宽 wi.深 di.高 hi. 箱子不能翻转,将箱子堆起来时,下面箱子的宽度.高度和深度必须大于上面的箱子. 实现一种方法,搭出最高的一堆箱子.箱堆的高度为每 ...

  4. 程序员面试金典 - 面试题 17.08. 马戏团人塔(最长上升子序 DP/二分查找)

    文章目录 1. 题目 2. 解题 2.1 超时解 2.2 二分查找 1. 题目 有个马戏团正在设计叠罗汉的表演节目,一个人要站在另一人的肩膀上.出于实际和美观的考虑,在上面的人要比下面的人矮一点且轻一 ...

  5. 《程序员面试金典》解题目录(更新完毕)

    题目来源于LeetCode上的<程序员面试金典>,这里做一个目录方便大家查找.另外有本人的LeetCode解题目录.<剑指Offer>解题目录.LintCode代码能力测试CA ...

  6. C#LeetCode刷题-程序员面试金典

    本文由 比特飞 原创发布,欢迎大家踊跃转载. 转载请注明本文地址:C#LeetCode刷题-程序员面试金典 | .Net中文网. C#LEETCODE刷题概述 概述 所有LeetCode程序员面试金典 ...

  7. 《程序员面试金典》+《算法导论》

    <程序员面试金典>+<算法导论> 因为最近可能会面临一波面试,但是自己各种算法以及常见的问题的熟悉程度感觉还不够,但是由前几次的代码优化经验来看,算法优化可以说是代码优化的重中 ...

  8. 程序员面试金典——18.13 最大字母矩阵

    程序员面试金典--18.13 最大字母矩阵 在牛客网上把此题的难度给大大降低了......... Solution1: 参考网址:https://www.nowcoder.com/questionTe ...

  9. 程序员面试金典——18.12最大和子矩阵

    程序员面试金典--18.12最大和子矩阵 Solution1: 参考网址: [1]https://www.cnblogs.com/GodA/p/5237061.html 思想讲的很清楚~ [2]htt ...

最新文章

  1. 无事“自动驾驶”,有事“辅助驾驶”?
  2. 三种集中式总线判优控制
  3. (转)DevExpress 汉化(简单、实用、快速)
  4. SQLite 入门教程(三)好多约束 Constraints
  5. 使用Nginx反向代理部署laravel和history模式的Vue项目[更新]
  6. 了解冒泡排序选择排序
  7. 都在讨论高并发,结果连并发量、TPS、QPS都分不清
  8. 走进WebApiClientCore的设计
  9. python py2exe_转:py2exe 生成 python 可执行文件
  10. 基于JAVA+SpringBoot+Mybatis+MYSQL的校园招聘管理系统
  11. mysql md 123456_MySQL修炼之路四
  12. Navicat加载缓慢
  13. zip压缩文件暴力破解
  14. 技术文档模板_腾讯文档-轻松操作指南
  15. 【PS/PSD】237款日系小清新文艺唯美梦幻手绘插画分层PSD素材
  16. html5动态连线,canvas简单连线动画的实现代码
  17. 咪唑型离子液体修饰二氧化硅改性PVC薄膜|离子液体修饰碳纳米管(CNTs-ILE)化学试剂
  18. storm滑动时间窗口实现
  19. The Open Group 2018 北京峰会召开,看行业大咖都说了哈?
  20. 全新开发周易起名网PHP网站源码+后台修复版

热门文章

  1. 自定义Repeater数据控件的一个页面显示效果
  2. 数据结构上机实践第七周项目3 - 负数把正数赶出队列
  3. php 输出tab_php实现读取和写入tab分割的文件
  4. mysql 表变量_在MySQL中创建表变量
  5. mysql数据倾斜_sqoop数据倾斜解决实战
  6. 一年级abb式词语并造句_一年级语文ABB式词语专项练习附答案,考考孩子!
  7. python 去除水印_python 利用opencv去除图片水印
  8. 银行考试计算机重点知识,银行计算机考试试题
  9. 米思齐_米思齐公益培训之交互式图形设计与数据分析圆满落幕
  10. OpenCV-Python实战(12)——一文详解AR增强现实