面试题25-II:判断是否是二叉搜索树

Description:
输入一个整形数组,表示一颗满二叉树,判断是否是一颗二叉搜索树。

满二叉树:一颗二叉树,除了最后一层没有子节点,其他节点都有两个子节点。

二叉搜索树:一颗二叉树,若左子树不空,则左子树的所有节点值都小于它的根节点值;若右子树不空,则右子树的所有节点值都大于它的根节点值,且它的左右子树分别是二叉搜索树。

题目链接:牛客网链接

Analysis:
根据输入序列建立二叉树,再根据二叉搜索树特点,判断是否是二叉搜索树。

特点1:定义中的特点,左右子树大小关系;特点2:延伸特点,中序遍历二叉搜索树的序列是递增排序。
Solution:

	bool IsBST(TreeNode* root) {
        if (root == nullptr)
            return true;
        if (root->left && root->left->val >= root->val)
            return false;

        if (root->right && root->right->val <= root->val)
            return false;
        return IsBST(root->left) && IsBST(root->right);
    }

开始写成这样,不能覆盖所有case,比如10,5,15,3,11,13,18,正确判断是false,遗漏的点是左子树所有节点都小于它的根节点值,右子树所有节点都大于它的根节点。

修正解决: 判断根节点的左子树最大值小于等于根节点,右子树的最小值大于等于根节点,再递归左右子树,这样会有重复计算的问题。

再修正解决1: 利用二叉搜索树特点,左子树节点取值范围(INT_MIN, root->val),右子树节点取值范围(root->val, INT_MAX),如果节点不在这个范围,则报错。

	bool IsBST2(TreeNode* root) {
        return helper(root, INT_MIN, INT_MAX);
    }
    bool helper(TreeNode* root, int min, int max) {
        if (root == nullptr)
            return true;
        if (root->val <= min || root->val >= max)
            return false;
        return helper(root->left, min, root->val) && helper(root->right, root->val, max);
    }

再修正解决2: 中序遍历建立的二叉搜索树,判断是否是递增序列。

最后通过的完整代码:

#include <vector>
#include <queue>
#include <iostream>
using namespace std;
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int value) : val(value), left(nullptr), right(nullptr) {
    }
};
TreeNode* BuildTree(vector<int>& nums) {
    int len = nums.size();
    if (len == 0)
        return nullptr;
    TreeNode* root = new TreeNode(nums[0]);
    TreeNode* cur = root, *temp = nullptr;
    queue<TreeNode *> que;
    que.push(cur);
    for (int i = 1; i < len; i ++) {
        temp = new TreeNode(nums[i]);
        if (i % 2) {
            cur = que.front();
            cur->left = temp;
            que.pop();
        } else {
            cur->right = temp;
        }
        que.push(temp);
    }
    return root;
}

void Inorder(TreeNode* root, vector<int>& seqs) {
    if (root == nullptr)
        return;
    Inorder(root->left, seqs);
    seqs.push_back(root->val);
    Inorder(root->right, seqs);
}

bool IsBst(TreeNode* root) {
    vector<int> seqs;
    Inorder(root, seqs);
    for (int i = 1; i < seqs.size(); i ++) {
        if (seqs[i - 1] >= seqs[i])
            return false;
    }
    return true;
}

int main(void) {
    vector<int> nums;
    int n;
    char c;
    while (cin >> n) {
        nums.push_back(n);
        cin >> c;
    }
    TreeNode* root = BuildTree(nums);
    if (IsBst(root)) {
        cout << "True" << endl;
    } else {
        cout << "False" << endl;
    }

    return 0;
}

References:
[1] https://blog.csdn.net/sgbfblog/article/details/7771096
[2] https://cloud.tencent.com/developer/article/1531775

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值