【PAT】1127 ZigZagging on a Tree (30 分)

先dfs还原树,

然后按行顺序存储(bfs),

输出时两行循环一次即可。

//我的解法:
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

vector<int> in,post,result[31];//最多保证31行就够了
struct node
{
    int data;
    node* lchild,* rchild;
};

struct nnode
{
    node* addr;
    int level;//从0开始
};



node* lca(int inl,int inr,int postl,int postr){
    if(inl>inr) return NULL;
    int i=inl;
    while(in[i]!=post[postr]) i++;
    node* root=new node;
    root->data=post[postr];
    root->lchild=lca(inl,i-1,postl,postl+(i-inl)-1);
    root->rchild=lca(i+1,inr,postl+(i-inl),postr-1);
    return root;
}

void groupByT(node* root){
    if(!root) return;
    queue<nnode> q;
    q.push(nnode{root,0});
    while(!q.empty()){
        nnode tmp=q.front();
        q.pop();
        result[tmp.level].push_back(tmp.addr->data);
        if(tmp.addr->lchild) q.push(nnode{tmp.addr->lchild,tmp.level+1});
        if(tmp.addr->rchild) q.push(nnode{tmp.addr->rchild,tmp.level+1});
    } 
}

int main(){
    int n;
    scanf("%d",&n);
    in.resize(n),post.resize(n);
    for(int i=0;i<n;i++) scanf("%d",&in[i]);
    for(int i=0;i<n;i++) scanf("%d",&post[i]);
    node* root=NULL;
    root=lca(0,n-1,0,n-1);

    groupByT(root);

    printf("%d",result[0][0]);//第0行只有一个数,恰好先输出保证空格
    for(int i=1;i<31;i++){
        if(i%2==1){
            for(int j=0;j<result[i].size();j++){
                printf(" %d",result[i][j]);
            }
        }else{
            for(int j=result[i].size()-1;j>=0;j--){
                printf(" %d",result[i][j]);
            }
        }
    }
    
    return 0;
}

 

//柳姐解法
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
using namespace std;

vector<int> in,post,result[35];
int tree[35][2],root;
struct node
{
    int index,depth;
};


void dfs(int &index,int inl,int inr,int postl,int postr){
    if(inl>inr) return;
    index=postr;
    int i=inl;
    while(in[i]!=post[postr]) i++;
    
    dfs(tree[index][0],inl,i-1,postl,postl+(i-inl)-1);//共(i-inl)个数
    dfs(tree[index][1],i+1,inr,postl+(i-inl),postr-1);//post左右子树中间连续
}


void bfs(){
   queue<node> q;
   q.push(node{root,0});//tree[]里没有root
   while(!q.empty()){
       node tmp=q.front();
       q.pop();
       result[tmp.depth].push_back(post[tmp.index]);//按行存储啊~
       if(tree[tmp.index][0]!=0){
           q.push(node{tree[tmp.index][0],tmp.depth+1});
       }
       if(tree[tmp.index][1]!=0){
           q.push(node{tree[tmp.index][1],tmp.depth+1});
       }
   }
}

int main(){
    int n;
    scanf("%d",&n);
    in.resize(n+1),post.resize(n+1);//为啥只能n+1?
    for(int i=1;i<=n;i++) scanf("%d",&in[i]);
    for(int i=1;i<=n;i++) scanf("%d",&post[i]);
    dfs(root,1,n,1,n);
    bfs();

    printf("%d",result[0][0]);
    for(int i=1;i<35;i++){//[0][0]已经输出了
        if(i%2==1){
            for(int j=0;j<result[i].size();j++){
                printf(" %d",result[i][j]);
            }
        }else{
            for(int j=result[i].size()-1;j>=0;j--){
                printf(" %d",result[i][j]);
            }
        }
    }
    
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值