PAT 甲级 1043 Is It a Binary Search Tree (25 分) 假设法

题意见:

https://blog.csdn.net/xiang_6/article/details/100535189

思路:

这个解法比上一个简单,上一个解法要分类型,找分割点,要想挺多

这个解法就是假设给定的先序遍历符合两种类型的bst中的一种,然后按照两种树的的方式分别建树,中间不合法的情况标记出来,最后看符合那种类型的树,输出

 

 

#include<bits/stdc++.h>

using namespace std;
const int maxn = 1e3 + 7;

int n, t, id = 1, cnt = 0;
int a[maxn];
bool ok1 = true, ok2 = true;
struct node {
    int v;
    int l, r;
}t1[maxn], t2[maxn];

void bstinit(int l, int r, int &root) {
    //cout << l << " ++++ " << r << endl;
    if(l > r) return;
    root = id++;
    t1[root].v = a[l];
    int i;
    for(i = l+1; i <= r; ++i) if(a[i] > a[l]) break;
    for(int j = i; j <= r; ++j) {
        if(a[j] < a[l]) {
            ok1 = false;
            return;
        }
    }
    bstinit(l+1, i-1, t1[root].l);
    bstinit(i, r, t1[root].r);
}
void mstinit(int l, int r, int &root) {
    if(l > r) return;
    root = id++;
    t2[root].v = a[l];
    int i;
    for(i = l+1; i <= r; ++i) if(a[i] < a[l]) break;
    for(int j = i; j <= r; ++j) {
        if(a[j] > a[l]) {
            ok2 = false;
            return;
        }
    }
    mstinit(l+1, i-1, t2[root].l);
    mstinit(i, r, t2[root].r);
}
void print1(int id) {
    if(!id) return;
    print1(t1[id].l);
    print1(t1[id].r);
    if(cnt) {
        printf(" %d", t1[id].v);
    }
    else {
        cnt = 1;
        printf("%d", t1[id].v);
    }
}
void print2(int id) {
    if(!id) return;
    print2(t2[id].l);
    print2(t2[id].r);
    if(cnt) {
        printf(" %d", t2[id].v);
    }
    else {
        cnt = 1;
        printf("%d", t2[id].v);
    }
}
int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) {
        scanf("%d", &a[i]);
    }
    bstinit(1, n, t); id = 1;
    mstinit(1, n, t);
    if(ok1) {
        puts("YES");
        print1(1);
    }
    else if(ok2) {
        puts("YES");
        print2(1);
    }
    else {
        puts("NO");
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值