• 《剑指offer》第六十八题:树中两个结点的最低公共祖先


    // 面试题68:树中两个结点的最低公共祖先
    // 题目:输入两个树结点,求它们的最低公共祖先。
    
    #include <cstdio>
    #include "Tree.h"
    #include <list>
    
    using namespace std;
    
    // 得到树结点的路径
    bool GetNodePath(const TreeNode* pRoot, const TreeNode* pNode, list<const TreeNode*>& path)
    {
        if (pRoot == pNode) //找到了树结点
            return true;
    
        path.push_back(pRoot);
    
        bool found = false;
    
        vector<TreeNode*>::const_iterator i = pRoot->m_vChildren.begin();
        while (!found && i < pRoot->m_vChildren.end()) //遍历当前结点的所有子节点
        {
            found = GetNodePath(*i, pNode, path);
            ++i;
        }
    
        if (!found) //如果不包含找的树结点则删除路径中当前节点
            path.pop_back();
    
        return found;
    }
    
    // 得到最后一个公共节点
    const TreeNode* GetLastCommonNode
    (
        const list<const TreeNode*>& path1,
        const list<const TreeNode*>& path2
    )
    {
        list<const TreeNode*>::const_iterator iterator1 = path1.begin();
        list<const TreeNode*>::const_iterator iterator2 = path2.begin();
    
        const TreeNode* pLast = nullptr;
    
        while (iterator1 != path1.end() && iterator2 != path2.end())
        {
            if (*iterator1 == *iterator2)
                pLast = *iterator1;
    
            iterator1++;
            iterator2++;
        }
        return pLast;
    }
    
    // 最后一个公共父节点
    const TreeNode* GetLastCommonParent(const TreeNode* pRoot, const TreeNode* pNode1, const TreeNode* pNode2)
    {
        //第一个节点路径
        list<const TreeNode*> path1;
        GetNodePath(pRoot, pNode1, path1);
    
        //第二个节点路径
        list<const TreeNode*> path2;
        GetNodePath(pRoot, pNode2, path2);
    
        return GetLastCommonNode(path1, path2);
    }
    // ====================测试代码====================
    void Test(const char* testName, const TreeNode* pRoot, const TreeNode* pNode1, const TreeNode* pNode2, TreeNode* pExpected)
    {
        if (testName != nullptr)
            printf("%s begins: ", testName);
    
        const TreeNode* pResult = GetLastCommonParent(pRoot, pNode1, pNode2);
    
        if ((pExpected == nullptr && pResult == nullptr) ||
            (pExpected != nullptr && pResult != nullptr && pResult->m_nValue == pExpected->m_nValue))
            printf("Passed.
    ");
        else
            printf("Failed.
    ");
    }
    
    // 形状普通的树
    //              1
    //            /   
    //           2     3
    //       /       
    //      4         5
    //     /       / |  
    //    6   7    8  9  10
    void Test1()
    {
        TreeNode* pNode1 = CreateTreeNode(1);
        TreeNode* pNode2 = CreateTreeNode(2);
        TreeNode* pNode3 = CreateTreeNode(3);
        TreeNode* pNode4 = CreateTreeNode(4);
        TreeNode* pNode5 = CreateTreeNode(5);
        TreeNode* pNode6 = CreateTreeNode(6);
        TreeNode* pNode7 = CreateTreeNode(7);
        TreeNode* pNode8 = CreateTreeNode(8);
        TreeNode* pNode9 = CreateTreeNode(9);
        TreeNode* pNode10 = CreateTreeNode(10);
    
        ConnectTreeNodes(pNode1, pNode2);
        ConnectTreeNodes(pNode1, pNode3);
    
        ConnectTreeNodes(pNode2, pNode4);
        ConnectTreeNodes(pNode2, pNode5);
    
        ConnectTreeNodes(pNode4, pNode6);
        ConnectTreeNodes(pNode4, pNode7);
    
        ConnectTreeNodes(pNode5, pNode8);
        ConnectTreeNodes(pNode5, pNode9);
        ConnectTreeNodes(pNode5, pNode10);
    
        Test("Test1", pNode1, pNode6, pNode8, pNode2);
    }
    
    // 树退化成一个链表
    //               1
    //              /
    //             2
    //            /
    //           3
    //          /
    //         4
    //        /
    //       5
    void Test2()
    {
        TreeNode* pNode1 = CreateTreeNode(1);
        TreeNode* pNode2 = CreateTreeNode(2);
        TreeNode* pNode3 = CreateTreeNode(3);
        TreeNode* pNode4 = CreateTreeNode(4);
        TreeNode* pNode5 = CreateTreeNode(5);
    
        ConnectTreeNodes(pNode1, pNode2);
        ConnectTreeNodes(pNode2, pNode3);
        ConnectTreeNodes(pNode3, pNode4);
        ConnectTreeNodes(pNode4, pNode5);
    
        Test("Test2", pNode1, pNode5, pNode4, pNode3);
    }
    
    // 树退化成一个链表,一个结点不在树中
    //               1
    //              /
    //             2
    //            /
    //           3
    //          /
    //         4
    //        /
    //       5
    void Test3()
    {
        TreeNode* pNode1 = CreateTreeNode(1);
        TreeNode* pNode2 = CreateTreeNode(2);
        TreeNode* pNode3 = CreateTreeNode(3);
        TreeNode* pNode4 = CreateTreeNode(4);
        TreeNode* pNode5 = CreateTreeNode(5);
    
        ConnectTreeNodes(pNode1, pNode2);
        ConnectTreeNodes(pNode2, pNode3);
        ConnectTreeNodes(pNode3, pNode4);
        ConnectTreeNodes(pNode4, pNode5);
    
        TreeNode* pNode6 = CreateTreeNode(6);
    
        Test("Test3", pNode1, pNode5, pNode6, nullptr);
    }
    
    // 输入nullptr
    void Test4()
    {
        Test("Test4", nullptr, nullptr, nullptr, nullptr);
    }
    
    int main(int argc, char* argv[])
    {
        Test1();
        Test2();
        Test3();
        Test4();
    
        return 0;
    }
    测试代码

    分析:知识迁移能力很重要。

  • 相关阅读:
    firstresponder 后,键盘不显示
    performSelector
    setNeedsDisplay、setNeedsLayout 区别
    Xcode 工程文件打开不出来, cannot be opened because the project file cannot be parsed.
    GCD介绍(一):基本概念和dispatch queues
    一些概念
    /mnt/sdcard /sdcard
    eclipse 导入已存在的工程文件出错
    ios 常用技巧
    ios nsstring去掉换行符
  • 原文地址:https://www.cnblogs.com/ZSY-blog/p/12702270.html
Copyright © 2020-2023  润新知