L2-004 二叉搜索树

#include <stdio.h>
#include <stdbool.h>

#define MAX_N 1000

int pre[MAX_N];          // 存储前序遍历序列
int post[MAX_N];         // 存储后序遍历序列
int post_idx = 0;        // 后序遍历的索引
bool is_mirror = false;  // 是否是镜像的标志

// 检查是否是二叉搜索树或其镜像的前序遍历
bool is_bst(int left, int right) {
    if (left > right) return true;  // 递归终止条件

    int root = pre[left];  // 当前子树的根节点
    int i = left + 1;      // 左子树的起始位置
    int j = right;         // 右子树的结束位置

    if (!is_mirror) {
        // 检查左子树(所有值小于根节点)
        while (i <= right && pre[i] < root) i++;
        // 检查右子树(所有值大于等于根节点)
        while (j > left && pre[j] >= root) j--;
    } else {
        // 检查镜像的左子树(所有值大于等于根节点)
        while (i <= right && pre[i] >= root) i++;
        // 检查镜像的右子树(所有值小于根节点)
        while (j > left && pre[j] < root) j--;
    }

    // 如果左子树和右子树的边界不匹配,则不是BST或其镜像
    if (i - j != 1) return false;

    // 递归检查左子树和右子树
    bool left_valid = is_bst(left + 1, j);
    bool right_valid = is_bst(i, right);

    // 将根节点加入后序遍历序列
    post[post_idx++] = root;

    return left_valid && right_valid;
}

int main() {
    int N;
    scanf("%d", &N);  // 输入节点数

    // 输入前序遍历序列
    for (int i = 0; i < N; i++) {
        scanf("%d", &pre[i]);
    }

    // 先假设是BST,检查是否满足条件
    bool valid = is_bst(0, N - 1);

    if (!valid) {
        // 如果不是BST,尝试检查是否是镜像
        is_mirror = true;
        post_idx = 0;  // 重置后序遍历索引
        valid = is_bst(0, N - 1);
    }

    if (valid) {
        printf("YES\n");  // 输出YES
        // 输出后序遍历序列
        for (int i = 0; i < N; i++) {
            if (i != 0) printf(" ");
            printf("%d", post[i]);
        }
        printf("\n");
    } else {
        printf("NO\n");  // 输出NO
    }

    return 0;
}

全部评论

相关推荐

团子请爱我一次_十月...:不是戈门,干哪来了,这就是java嘛
点赞 评论 收藏
分享
27届毕业,最近想找一段大厂实习,感觉简历有些问题,好多都不给面,求大佬们指点,最近好焦虑
重生之我学Java干...:我从后端的角度分析一下你的第一个项目,我感觉亮点不是很突出。因为我是因为组内有需求,临时上手学react干活。我用到的技术基本就cover你那个智慧园区管理平台的很多亮点了。那作为比较专业的前端,你上述的内容是不是有点单薄呢。感觉还得包装
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务