zoukankan      html  css  js  c++  java
  • pat 1151

    1151 LCA in a Binary Tree (30分)

     

    The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has both U and V as descendants.

    Given any two nodes in a binary tree, you are supposed to find their LCA.

    Input Specification:

    Each input file contains one test case. For each case, the first line gives two positive integers: M (≤ 1,000), the number of pairs of nodes to be tested; and N (≤ 10,000), the number of keys in the binary tree, respectively. In each of the following two lines, N distinct integers are given as the inorder and preorder traversal sequences of the binary tree, respectively. It is guaranteed that the binary tree can be uniquely determined by the input sequences. Then M lines follow, each contains a pair of integer keys U and V. All the keys are in the range of int.

    Output Specification:

    For each given pair of U and V, print in a line LCA of U and V is A. if the LCA is found and A is the key. But if A is one of U and V, print X is an ancestor of Y. where X is A and Y is the other node. If U or V is not found in the binary tree, print in a line ERROR: U is not found. or ERROR: V is not found. or ERROR: U and V are not found.

    Sample Input:

    6 8
    7 2 3 4 6 5 1 8
    5 3 7 2 6 4 8 1
    2 6
    8 1
    7 9
    12 -3
    0 8
    99 99

    Sample Output:

    LCA of 2 and 6 is 3.
    8 is an ancestor of 1.
    ERROR: 9 is not found.
    ERROR: 12 and -3 are not found.
    ERROR: 0 is not found.
    ERROR: 99 and 99 are not found.

    题意:给定一颗二叉树的前序和中序遍历序列,给出m对结点a,b,要求求出a,b的最深公共祖先结点

    思路:不需要建树,对于一个结点c,假如在中序遍历序列中,考虑a,b,c在中序遍历中出现的位置, 

        如果a<c&&b>c或者a>c&&b<c,那么c一定是a,b的最深公共祖先

        如果a<c&&b<c或者a>c&&b>c,那么a,b的最深公共祖先在c的左子树或者右子树中

        如果a==c或者b==c,那么a,b的最深公共祖先是a或者b

       按照这个思路递归即可,递归入口是根节点

    注意点:记录某个结点在中序遍历中的位置的时候要用map而不能用普通数组hash表示,因为结点的值可能是负数,这样会发生数组越界错误。

    代码如下:

    #include<cstdio>
    #include<map>
    using namespace std;
    
    int pre[10100];
    int in[10100];
    map<int,int> all;
    void lca(int inl,int inr,int preRoot,int a,int b){
        if(inl>inr)
            return;
        int inRoot=all[pre[preRoot]];
        int ina=all[a];
        int inb=all[b];
        if(ina<inRoot&&inb<inRoot)
            lca(inl,inRoot-1,preRoot+1,a,b);
        else if((ina<inRoot&&inb>inRoot)||(ina>inRoot&&inb<inRoot))
            printf("LCA of %d and %d is %d.
    ",a,b,pre[preRoot]);
        else if(ina>inRoot&&inb>inRoot)
            lca(inRoot+1,inr,preRoot+1+inRoot-inl,a,b);
        else if(ina==inRoot){
            printf("%d is an ancestor of %d.
    ",a,b);
        }
        else if(inb==inRoot)
            printf("%d is an ancestor of %d.
    ",b,a);
    }
    int main(){
        int m,n;
        scanf("%d%d",&m,&n);
        for(int i=1;i<=n;i++){
            scanf("%d",in+i);
            all[in[i]]=i;
        }
        for(int i=1;i<=n;i++){
            scanf("%d",pre+i);
        }
        int a,b;
        for(int i=0;i<m;i++){
            scanf("%d%d",&a,&b);
            if(all[a]==0&&all[b]==0)
                printf("ERROR: %d and %d are not found.
    ",a,b);
            else if(all[a]==0||all[b]==0)
                printf("ERROR: %d is not found.
    ",all[a]==0?a:b);
            else
                lca(1,n,1,a,b);
        }
        return 0;
    }
  • 相关阅读:
    Python 语言规范(Google)
    Python 代码风格规范(Google)
    GBM,XGBoost,LightGBM
    面试编程总结
    MagicNotes:如何迈向工作的坦途
    番茄工作法:让时间变成你最好的朋友
    时间管理:如何高效地利用时间
    读点大脑科学,学会变得更聪明
    为什么我那么努力,吃了那么多苦,也没见那么优秀?(转自知乎)
    不要被懒惰夺走你的思考能力
  • 原文地址:https://www.cnblogs.com/foodie-nils/p/13330070.html
Copyright © 2011-2022 走看看