(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/74612786冷血之心的博客)

剑指Offer(第二版)面试案例:树中两个节点的最低公共祖先节点


题目:输入两个树节点,求它们的最低公共祖先节点。


反问:这棵树是不是二叉树?


面试官:是二叉树,并且是二叉搜索树。


思路:

二叉搜索树是经过排序的,位于左子树的节点都比父节点小,位于右子树的节点都比父节点大。既然要找最低的公共祖先节点,我们可以从根节点开始进行比较。

若当前节点的值比两个节点的值都大,那么最低的祖先节点一定在当前节点的左子树中,则遍历当前节点的左子节点;

反之,若当前节点的值比两个节点的值都小,那么最低的祖先节点一定在当前节点的右子树中,则遍历当前节点的右子节点;

这样,直到找到一个节点,位于两个节点值的中间,则找到了最低的公共祖先节点。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null||root==p||root==q)
            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);
        else
            return root;
    }
}


面试官:如果只是普通的二叉树呢?


反问:树的节点中有没有指向父节点的指针?


面试官:为什么需要指向父节点的指针?


答:如果存在parent指针,则分别从输入的p节点和q节点指向root根节点,其实这就是两个单链表。问题转化为求两个单链表相交的第一个公共节点


详见:链表基础题大全(一)



面试官:那如果不存在parent指针呢?

递归的解法如下:

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null||root==p||root==q)
            return root;
        TreeNode left = lowestCommonAncestor(root.left,p,q);
        TreeNode right = lowestCommonAncestor(root.right,p,q);
        if (left == null)
            return right;
        if (right == null)
            return left;
        return root;
    }

迭代解法:

需要我们保存下由root根节点到p和q节点的路径,并且将路径存入list中,则问题转化为求两个list集合的最后一个共同元素。

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null || p==null || q==null)
        	return null;
        List<TreeNode> pathp = new ArrayList<>();
        List<TreeNode> pathq = new ArrayList<>();
        pathp.add(root);
        pathq.add(root);  

        getPath(root, p, pathp);
        getPath(root, q, pathq);  

        TreeNode lca = null;
        for(int i=0; i<pathp.size() && i<pathq.size(); i++) {
            if(pathp.get(i) == pathq.get(i))
            	lca = pathp.get(i);
            else
            	break;
        }
        return lca;
    }  

    private boolean getPath(TreeNode root, TreeNode n, List<TreeNode> path) {
        if(root==n)
            return true;  

        if(root.left!=null) {
            path.add(root.left);
            if(getPath(root.left, n, path))
            	return true;
            path.remove(path.size()-1);
        }  

        if(root.right!=null) {
            path.add(root.right);
            if(getPath(root.right, n, path))
            	return true;
            path.remove(path.size()-1);
        }
        return false;
    }

该题是互联网面试中出现频率贼高的二叉树题目。必须掌握哦~

如果对你有帮助,记得点赞哦~欢迎大家关注我的博客,可以进群366533258一起交流学习哦~

本群给大家提供一个学习交流的平台,内设菜鸟Java管理员一枚、精通算法的金牌讲师一枚、Android管理员一枚、蓝牙BlueTooth管理员一枚、Web前端管理一枚以及C#管理一枚。欢迎大家进来交流技术。

剑指Offer(第二版)面试案例:树中两个节点的最低公共祖先节点的更多相关文章

  1. 【剑指Offer面试编程题】题目1509:树中两个结点的最低公共祖先--九度OJ

    题目描述: 给定一棵树,同时给出树中的两个结点,求它们的最低公共祖先. 输入: 输入可能包含多个测试样例. 对于每个测试案例,输入的第一行为一个数n(0<n<1000),代表测试样例的个数 ...

  2. 《剑指offer(第二版)》面试题55——判断是否为平衡二叉树

    一.题目大意 输入一颗二叉树,判断该二叉树是否为平衡二叉树(AVL树). 二.题解 <剑指offer>上给出了两种解决方式: 1.第一种是从根节点开始,从上往下遍历每个子节点并计算以子节点 ...

  3. 剑指Offer - 九度1509 - 树中两个结点的最低公共祖先

    剑指Offer - 九度1509 - 树中两个结点的最低公共祖先2014-02-07 01:04 题目描述: 给定一棵树,同时给出树中的两个结点,求它们的最低公共祖先. 输入: 输入可能包含多个测试样 ...

  4. 【剑指Offer学习】【面试题50:树中两个结点的最低公共祖先】

    题目:求树中两个结点的最低公共祖先,此树不是二叉树,而且没有指向父节点的指针. 树的结点定义 private static class TreeNode { int val; List<Tree ...

  5. 《剑指offer》第六十八题(树中两个结点的最低公共祖先)

    // 面试题68:树中两个结点的最低公共祖先 // 题目:输入两个树结点,求它们的最低公共祖先. #include <iostream> #include "Tree.h&quo ...

  6. (剑指Offer)面试题50:树中两个结点的最低公共祖先

    题目: 求树中两个结点的最低公共祖先 思路: 考虑一下几种情况: 1.该树为二叉搜索树 二叉搜索树是排序树,位于左子树点的结点都比父结点小,而位于右子树的结点都比父结点大,只需要从树的根结点开始和两个 ...

  7. 树中两个结点的最低公共祖先--java

    题目:对于任意一个树,不仅仅限于二叉树,求树中两个结点的最低公共祖先结点. 解析:对于任意一棵树,显然并不局限于二叉树,也就是说树的非叶子结点可能存在多个子节点.所以,我们可以定义两个链表结构,存储这 ...

  8. 《剑指offer 第二版》题解

    剑指Offer 按题号排序 面试题 3:数组中重复的数字 面试题 4:二维数组中的查找 面试题 5:替换空格 面试题 6:从头到尾打印链表 面试题 7:重建二叉树 面试题 8:二叉树的下一个节点 面试 ...

  9. 《剑指offer(第二版)》面试题60——n个骰子的点数

    一.题目描述 把n个骰子仍在地上,所有的骰子朝上的一面的点数之和为s,输入n,打印出s所有可能的值出现的概率. 二.题解 <剑指offer>上给出的两种方法,尤其是代码,晦涩难懂且没有注释 ...

随机推荐

  1. 剑指offer(第2版)刷题 Python版汇总

    剑指offer面试题内容 第2章 面试需要的基础知识 面试题1:赋值运算符函数 面试题2:实现Singleton模式  解答 面试题3:数组中重复的数字 解答 面试题4:二维数组中的查找 解答 面试题 ...

  2. DP专题·四(树形dp)

    1.poj 115 TELE 题意:一个树型网络上有n个结点,1~n-m为信号传送器,n-m+1~n为观众,当信号传送给观众后,观众会付费观看,每铺设一条道路需要一定费用.现在求以1为根,使得收到观众 ...

  3. NHibernate之配置文件属性说明

    一.NHibernate配置所支持的属性 属性名 用途 dialect 设置NHibernate的Dialect类名 - 允许NHibernate针对特定的关系数据库生成优化的SQL 可用值: ful ...

  4. article嵌套

    例如: 为了将每一个部分都突出显示,可以将article添加边框和颜色的属性: <style> article{ border: 1px solid #ff0000; margin: 5p ...

  5. 苹果Dock样式的菜单

    在线演示 本地下载

  6. 新机git及github sshkey简单配置

    新机git简单配置,毕竟不常用,不用每次都查1.安装gitwindows:https://git-scm.com/download/winubuntu: apt install git 2.全局配置 ...

  7. BeatSaber节奏光剑插件开发官方教程2-简单的插件示例

    原文:https://wiki.assistant.moe/modding/example-mod 一.在开始之前 1 确保你已经看过教你如何添加插件模板的教程,且你已经使用插件模板创建了一个新项目 ...

  8. BZOJ-5424: 烧桥计划(单调队列)

    BZOJ-5424: 烧桥计划(单调队列) 题目链接 题解: 先考虑最暴力的\(dp\):设\(f[k][i]\)表示搞掉第\(1\sim i\)段,烧了\(k\)段的最小花费,设\(calc(x,y ...

  9. eclipse中去掉警告提示

    有时候我们要去掉这些不必要的提示 下面我们来设置去掉这些警告提示

  10. 编写一个程序,将 d:\java 目录下的所有.java 文件复制到 d:\jad 目录下,并将原来文件的扩展名从.java 改为.jad。

    package IO; import java.io.*; public class FileCopy { public static void main(String[] args) throws ...