1151 LCA in a Binary Tree (30 point(s))找共同祖先同一道408真题思路!!

这个共同祖先像不像那道找shared链表算法真题!不过真题答案只找到了公共值结点就算后边一致,万一后边不是共同后缀呢,感觉还得用栈,从最后一个元素开始弹出!

代码思路:找路径(分别到u,v停止)
然后相当于那道真题,弹出第一个相同元素的是LCA

在这里插入图片描述
真的太顺利了,运行一次就全对!

#include<iostream>
#include<stack>
using namespace std;
int in[10003],pre[10003],u,v;
struct node{
    int data;
    node *left,*right;
};
void create_tree(node* &root,int l1,int l2,int len){               //前序中序建树
    if(len==0) return;
    root=new node;
    root->data=pre[l1];
    if(len==1) return;
    int i;
    for(i=l2;i<l2+len;i++){
        if(in[i]==pre[l1]) break;
    }
    create_tree(root->left,l1+1,l2,i-l2);
    create_tree(root->right,l1+len-lr,i+1,len-i+l2-1);
}
bool searchNode(node *root,int x ,stack<node*> &s) {                  //找路径
        if(root == NULL) return false;
        s.push(root);
        if(root->data == x) return true;
        bool b = false;
        if(root->left != NULL) b = searchNode(root->left,x,s);
        if(!b && root->right != NULL) b = searchNode(root->right,x,s);
        if(!b) s.pop();
        return b;
    }
void print_LCA(node* p,stack<node*> su,stack<node*> sv){
    if(!su.size()&&!sv.size()){
        cout<<"ERROR: "<<u<<" and "<<v<<" are not found."<<endl;return;
    }
    else if(!sv.size()){
        cout<<"ERROR: "<<v<<" is not found."<<endl; return;
    }
    else if(!su.size()){
        cout<<"ERROR: "<<u<<" is not found."<<endl; return;
    }
    else{
        if(su.size()>sv.size()){                                     //使路径长度相等时再从后往前弹出,想象两条shared链表
            while(su.size()!=sv.size()) su.pop();
        }
        else{
            while(su.size()!=sv.size()) sv.pop();
        }
        node *x=su.top(),*y=sv.top();
        while(su.size()>0&&x->data!=y->data){
            su.pop();
            sv.pop();
            x=su.top();
            y=sv.top();
        }
        if(x->data==y->data){
            if(x->data==u)
                cout<<u<<" is an ancestor of "<<v<<"."<<endl;
            else if(y->data==v)
                cout<<v<<" is an ancestor of "<<u<<"."<<endl;
            else{
                node* p=su.top();
                cout<<"LCA of "<<u<<" and "<<v<<" is "<<p->data<<"."<<endl;
            }
        }
   }
}
int main(){
    int m,n;
    cin>>m>>n;
    for(int i=0;i<n;i++) cin>>in[i];
    for(int i=0;i<n;i++) cin>>pre[i];
    node* root;
    create_tree(root,0,0,n);
    for(int i=0;i<m;i++){
        stack<node*> su,sv;
        cin>>u>>v;
        searchNode(root,u,su);
        searchNode(root,v,sv);
        print_LCA(root,su,sv);
    }
    return 0;
}

注意:误以为用栈实现先序遍历,并找到给定结点为止可以得到一条由跟结点到该结点的路径,结果确实差不多可以,但是栈中会少了一个给定结点的父结点。

void preorder(node* p,int x,stack<node*> &temp,int t){
     while(p!=NULL||temp.size()>0){
         while(p!=NULL){
             temp.push(p);
             if(p->data==x&&t==1){
                 tagu=1;return;
             }
             else if(p->data==x&&t==2){
                 tagv=1;return;
             }
             p=p->left;
         }
         p=temp.top();
         temp.pop();
         p=p->right;
     }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值