关闭

98. Validate Binary Search Tree

95人阅读 评论(0) 收藏 举报
分类:
Given a binary tree, determine if it is a valid binary search tree (BST).

Assume a BST is defined as follows:

The left subtree of a node contains only nodes with keys less than the node's key.
The right subtree of a node contains only nodes with keys greater than the node's key.
Both the left and right subtrees must also be binary search trees.

基本问题,判定二叉查找树是否成立。注意binary tree,二叉树,只是形状上有要求,只有二叉查找树,也就是这里的BST,才有我们通常意义上的左小右大性质。这里的验证第一反应就是递归啊,每一次递归要求左子树小于根,右子树大于根。但注意,这只是局部的要求,整体上还得保持一致,还得保持跟之前的节点间的大小关系。所以我们递归函数不仅传递节点,还传递合理的动态范围。

方法一:divide and conquer

bool isValidBST(TreeNode* root) {
    return helper(root, INT_MIN, INT_MAX);
}
bool helper (TreeNode* t, int val_min, int val_max) {
    if (t == NULL) return true;
    if (t->val >= val_min && t->val <= val_max) {
        if (t->left != NULL) {
            if (val_min == t->val) return false;//避免二者都是INT_MIN
            if (!helper(t->left, val_min, t->val-1)) return false;
        }
        if (t->right != NULL) {
            if (val_max == t->val) return false;//避免二者都是INT_MAX
            if (!helper(t->right, t->val+1, val_max)) return false;
        }
        return true;
    }
    return false;
}

其实这里的递归很好解决,需要注意的问题是动态范围的范围问题,因为测试用例里出现了很多INT的最大最小值。所以我们采用了闭区间作为范围,保证了可以等于INT_MAX, INT_MIN, 然后传递新的动态范围的时候提前做了预判,如果两者都等于MAX或者MIN,加一减一都失效,所以提前判断下。

方法二:中序遍历二叉树inorder traverse

因为二叉查找树中序遍历后输出应该是升序序列,所以可以从这一点上遍历BST来检查。
version 1:

bool isValidBST(TreeNode *root) {
    vector<int> res;
    printTree(root, res);
    for (int i = 1; i < res.size(); i++) {
        if (res[i] <= res[i-1]) return false;
    }
    return true;
}
void printTree (TreeNode *t, vector<int>& res) {
    if (t == NULL) return;
    if (t->left != NULL) printTree(t->left, res);
    res.push_back(t->val);
    if (t->right != NULL) printTree(t->right, res);
}

输出到int型数组里,再遍历数组。省去了数据类型的边界问题。
当然,也没有必要非要这么实在的把所有值存好,可以更进一步省去内存消耗。
version 2:

class Solution {
private: 
    TreeNode *lastNode = NULL;
public:
    bool isValidBST(TreeNode *root) {
        if (root == NULL) return true;
        if (!isValidBST(root->left)) return false;
        if (lastNode != NULL && lastNode->val >= root->val) return false;
        lastNode = root;
        return (isValidBST(root->right));
    }
};

用一个lastNode贯穿始终,因为我们只需要判断是否是严格的升序序列就行。

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:20727次
    • 积分:1708
    • 等级:
    • 排名:千里之外
    • 原创:146篇
    • 转载:4篇
    • 译文:1篇
    • 评论:2条
    文章分类
    最新评论