zoukankan      html  css  js  c++  java
  • (剑指Offer)面试题50:树中两个结点的最低公共祖先

    题目:

    求树中两个结点的最低公共祖先

    思路:

    考虑一下几种情况:

    1、该树为二叉搜索树

    二叉搜索树是排序树,位于左子树点的结点都比父结点小,而位于右子树的结点都比父结点大,只需要从树的根结点开始和两个输入的结点进行比较。

    如果当前结点的值比两个结点的值都大,那么最低的公共父结点一定在左子树,下一步就是遍历左子树;

    如果当前结点的值比两个结点的值都小,那么最低的公共父结点一定在右子树;下一步就是遍历右子树;

    如果当前结点的值介于两个结点的值之间,那么它就是两个结点的公共父结点,第一个找到的就是最低的公共父结点。

    2、该树为二叉树,结点中有指向父结点的指针

    有了父结点,就可以找到任意结点到根结点的路径;因此:

    分别找到从两个结点开始到根结点的路径,即两个链表;

    然后找到两个链表的第一个公共结点,就是最低的公共父结点;

    3、该树为普通的树

    从根结点开始,通过广度优先搜索,分别找到到达两个结点的路径;

    然后找到两条路径的第一个公共结点,就是最低的公共父结点;

    代码:

    暂时先实现第三种条件

    struct TreeNode{
        int val;
        vector<TreeNode*> children;
    };
    
    bool GetNodePath(TreeNode* pRoot,TreeNode* pNode,list<TreeNode*> &path){
        if(pRoot==pNode)
            return true;
        path.push_back(pRoot);
    
        vector<TreeNode*>::iterator it=pRoot->children.begin();
        bool found = false;
        while(!found && it!=pRoot->children.end()){
            found=GetNodePath(*it,pNode,path);
            ++it;
        }
    
        if(!found)
            path.pop_back();
    
        return found;
    }
    
    TreeNode* GetLastCommonNode(const list<TreeNode*> &path1,const list<TreeNode*> &path2){
        list<TreeNode*>::const_iterator it1=path1.begin();
        list<TreeNode*>::const_iterator it2=path2.begin();
    
        TreeNode* pLast=NULL;
    
        while(it1!=path1.end() && it2!=path2.end()){
            if(*it1==*it2)
                pLast=*it1;
            it1++;
            it2++;
        }
        return pLast;
    }
    
    TreeNode* GetLastCommonParent(TreeNode* pRoot,TreeNode* pNode1,TreeNode* pNode2){
        if(pRoot==NULL || pNode1==NULL || pNode2==NULL)
            return NULL;
        list<TreeNode*> path1;
        GetNodePath(pRoot,pNode1,path1);
    
        list<TreeNode*> path2;
        GetNodePath(pRoot,pNode2,path2);
    
        return GetLastCommonNode(path1,path2);
    }
  • 相关阅读:
    【AS3代码】AS调用JS
    【AS3代码】MP3音乐的播放/暂停/设定音量大小
    【AS3代码】在上下文菜单(右键菜单)中添加自定义项
    【AS3代码】更换鼠标箭头样式,并跟随鼠标!
    【AS3代码】创建动态文本
    【AS3代码】播放FLV视频流的三步骤!
    【AS3代码】Timer计时器用法
    【AS3代码】指定间隔时间运行函数 及 停止运行函数
    【AS3代码】Keyboard键盘操作!
    多线程_传送带我们到底能走多远系列(6)
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4693045.html
Copyright © 2011-2022 走看看