• 九度:题目1509:树中两个结点的最低公共祖先


    题目描述:

    给定一棵树,同时给出树中的两个结点,求它们的最低公共祖先。

    输入:

    输入可能包含多个测试样例。
    对于每个测试案例,输入的第一行为一个数n(0<n<1000),代表测试样例的个数。
    其中每个测试样例包括两行,第一行为一个二叉树的先序遍历序列,其中左右子树若为空则用0代替,其中二叉树的结点个数node_num<10000。
    第二行为树中的两个结点的值m1与m2(0<m1,m2<10000)。

    输出:

    对应每个测试案例,
    输出给定的树中两个结点的最低公共祖先结点的值,若两个给定结点无最低公共祖先,则输出“My God”。

    样例输入:
    2
    1 2 4 6 0 0 7 0 0 5 8 0 0 9 0 0 3 0 0
    6 8
    1 2 4 6 0 0 7 0 0 5 8 0 0 9 0 0 3 0 0
    6 12

    样例输出:


    2
    My God
    Code:
    #include<stdio.h>
    #include<iostream>
    
    using namespace std;
    
    struct Node
    {
        int val;
        Node *left, *right;
        Node(int value):val(value),left(NULL),right(NULL){};
    };
    
    Node* p1, *p2;
    int value1, value2;
    void preorder_construct(Node** root)
    {
        int value;
        cin>>value;
        if(value==0)
            return;
        *root  = new Node(value);
        preorder_construct(&((*root)->left));
        preorder_construct(&((*root)->right));
    }
    
    
    void preorder_print(Node *root)
    {
        if(root==NULL)
            return;
        //cout<<root->val;
        if(root->val==value1)
            p1 = root;
        if(root->val==value2)
            p2 = root;
        preorder_print(root->left);
        preorder_print(root->right);
    }
    
    bool in_tree(Node *root, Node *p)
    {
        if(NULL==root)return false;
        if(root==p)return true;
        return in_tree(root->left, p)||in_tree(root->right,p);
    }
    
    int common_parent(Node *root, Node *p, Node *q)
    {
        if(NULL==root||NULL==p||NULL==q)
            return 0;
        if(!in_tree(root,p)||!in_tree(root,q))
            return 0;
        if(root==p)
            return root->val;
        if(root==q)
            return root->val;
    
        int left = common_parent(root->left, p, q) ;
        if(left!=0)
            return left;
        int right= common_parent(root->right, p, q) ;
        if(right!=0)
            return right;
        return root->val;
    }
    
    int main()
    {
        int tcase;
        freopen("test.in","r",stdin);
        freopen("test.out","w",stdout);
        Node* root;
        int result;
        cin>>tcase;
        while(tcase--)
        {
            p1 = NULL;
            p2 = NULL;
            preorder_construct(&root);
            cin>>value1>>value2;
            preorder_print(root);
            if(p1==NULL||p2==NULL)
            {
                cout<<"My God"<<endl;
                continue;
            }
            result = common_parent(root,p1, p2); 
            if(result)
                cout<<result<<endl;
            else
                cout<<"My God"<<endl;
        }
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
    1. 建树过程,这个树的输入是题目中定义的,所以建树的时候要用到先序建树
    2. 建树中,void preorder_construct(Node** root);
    这里传入的是二级指针,仔细体会
    3. 判断一个点是否在树中
    4. 判断两者最近祖先时,还要判断,此点是否在内
    5. 时间有点长对应每个测试案例,
    
    
    每天早上叫醒你的不是闹钟,而是心中的梦~
  • 相关阅读:
    windows下 CodeBlock13-12 实验 C++11 测试
    用矩阵运算实现最小二乘法曲线拟合算法
    winXP 系统下ubuntu-12.04 硬盘安装
    TCP服务器并发编程构架:完成端口IOCP模式
    TCP服务器并发编程构架:完成例程IRP模式
    续:双缓存队列_模板类
    双缓存静态循环队列(三)
    如何在只知道SQL_ID时,查询到此sql语句的执行计算机名称(是两三天前的SQL语句)
    RMAN Catalog 和 Nocatalog 的区别
    异机恢复后ORA-01152错误解决
  • 原文地址:https://www.cnblogs.com/vintion/p/4116837.html
Copyright © 2020-2023  润新知