[LeetCode] Validate Binary Search Tree 验证二叉搜索树

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.

confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ.

这道验证二叉搜索树有很多种解法,可以利用它本身的性质来做,即左<根<右,也可以通过利用中序遍历结果为有序数列来做,下面我们先来看最简单的一种,就是利用其本身性质来做,初始化时带入系统最大值和最小值,在递归过程中换成它们自己的节点值,用long代替int就是为了包括int的边界条件,代码如下:

解法一:

// Recursion without inorder traversal
class Solution {
public:
    bool isValidBST(TreeNode *root) {
        return isValidBST(root, LONG_MIN, LONG_MAX);
    }
    bool isValidBST(TreeNode *root, long mn, long mx) {
        if (!root) return true;
        if (root->val <= mn || root->val >= mx) return false;
        return isValidBST(root->left, mn, root->val) && isValidBST(root->right, root->val, mx);
    }
};

下面我们来看使用中序遍历来做,这种方法思路很直接,通过中序遍历将所有的节点值存到一个数组里,然后再来判断这个数组是不是有序的,代码如下:

解法二:

// Recursion
class Solution {
public:
    bool isValidBST(TreeNode *root) {
        if (!root) return true;
        vector<int> vals;
        inorder(root, vals);
        for (int i = 0; i < vals.size() - 1; ++i) {
            if (vals[i] >= vals[i + 1]) return false;
        }
        return true;
    }
    void inorder(TreeNode *root, vector<int> &vals) {
        if (!root) return;
        inorder(root->left, vals);
        vals.push_back(root->val);
        inorder(root->right, vals);
    }
};

下面这种解法跟上面那个很类似,都是用递归的中序遍历,但不同之处是不将遍历结果存入一个数组遍历完成再比较,而是每当遍历到一个新节点时和其上一个节点比较,如果不大于上一个节点那么则返回false,全部遍历完成后返回true。代码如下:

解法三:

// Still recursion
class Solution {
public:
    TreeNode *pre;
    bool isValidBST(TreeNode *root) {
        int res = 1;
        pre = NULL;
        inorder(root, res);
        if (res == 1) return true;
        else false;
    }
    void inorder(TreeNode *root, int &res) {
        if (!root) return;
        inorder(root->left, res);
        if (!pre) pre = root;
        else {
            if (root->val <= pre->val) res = 0;
            pre = root;
        }
        inorder(root->right, res);
    }
};

当然这道题也可以用非递归来做,需要用到栈,因为中序遍历可以非递归来实现,所以只要在其上面稍加改动便可,代码如下:

解法四:

// Non-recursion with stack
class Solution {
public:
    bool isValidBST(TreeNode *root) {
        if (!root) return true;
        stack<TreeNode*> s;
        TreeNode *p = root;
        TreeNode *pre = NULL;
        while (p || !s.empty()) {
            while (p) {
                s.push(p);
                p = p->left;
            }
            p = s.top();
            s.pop();
            if (!pre) pre = p;
            else {
                if (p->val <= pre->val) return false;
            }
            pre = p;
            p = p->right;
        }
        return true;
    }
};

最后还有一种方法,由于中序遍历还有非递归且无栈的实现方法,称之为Morris遍历,可以参考我之前的博客Binary Tree Inorder Traversal 二叉树的中序遍历,这种实现方法虽然写起来比递归版本要复杂的多,但是好处在于是O(1)空间复杂度,但是我的实现方法在本机上测试都能通过,在OJ上测试却有Runtime error,我找来找去不知道问题在哪,不管了先贴上来,说不定能引起某位大神的注意,帮小弟改一改哈~

解法五

// Non-recursion without stack, I don‘t know why it cannot pass OJ, which show Runtime error. Can anyone help me fix it? Thanks!
class Solution {
public:
    bool isValidBST(TreeNode *root) {
        if (!root) return true;
        TreeNode *cur, *pre, *parent = NULL;
        cur = root;
        while (cur) {
            if (!cur->left) {
                if (parent && parent->val >= cur->val) return false;
                parent = cur;
                cur = cur->right;
            } else {
                pre = cur->left;
                while (pre->right && pre->right != cur) pre = pre->right;
                if (!pre->right) {
                    pre->right = cur;
                    cur = cur->left;
                } else {
                    pre->right = NULL;
                    if (parent->val >= cur->val) return false;
                    parent = cur;
                    cur = cur->right;
                }
            }
        }
        return true;
    }
};
时间: 2024-08-07 16:44:01

[LeetCode] Validate Binary Search Tree 验证二叉搜索树的相关文章

[CareerCup] 4.5 Validate Binary Search Tree 验证二叉搜索树

4.5 Implement a function to check if a binary tree is a binary search tree. LeetCode上的原理,请参见我之前的博客Validate Binary Search Tree 验证二叉搜索树.

[LeetCode] 255. Verify Preorder Sequence in Binary Search Tree 验证二叉搜索树的先序序列

Given an array of numbers, verify whether it is the correct preorder traversal sequence of a binary search tree. You may assume each number in the sequence is unique. Follow up:Could you do it using only constant space complexity? 给一个数组,验证是否为一个二叉搜索树的

[LeetCode] Recover Binary Search Tree 复原二叉搜索树

Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing its structure. Note:A solution using O(n) space is pretty straight forward. Could you devise a constant space solution? confused what "{1,#,2,3}"

[LeetCode] Binary Search Tree Iterator 二叉搜索树迭代器

Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST. Calling next() will return the next smallest number in the BST. Note: next() and hasNext() should run in average O(1) time and uses

[LeetCode] 99. Recover Binary Search Tree 复原二叉搜索树

Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing its structure. Example 1: Input: [1,3,null,null,2]   1   /  3     2 Output: [3,1,null,null,2]   3   /  1     2 Example 2: Input: [3,1,4,null,null,2]

[leetcode]108. Convert Sorted Array to Binary Search Tree构建二叉搜索树

构建二叉搜索树 /* 利用二叉搜索树的特点:根节点是中间的数 每次找到中间数,左右子树递归子数组 */ public TreeNode sortedArrayToBST(int[] nums) { return builder(nums,0,nums.length-1); } public TreeNode builder(int[] nums,int left,int right) { if (left>right) return null; int mid = (left+right)/2;

669. Trim a Binary Search Tree 修剪二叉搜索树

Given a binary search tree and the lowest and highest boundaries as L and R, trim the tree so that all its elements lies in [L, R](R >= L). You might need to change the root of the tree, so the result should return the new root of the trimmed binary

173 Binary Search Tree Iterator 二叉搜索树迭代器

实现一个二叉搜索树迭代器.你将使用二叉搜索树的根节点初始化迭代器.调用 next() 将返回二叉搜索树中的下一个最小的数.注意: next() 和hasNext() 操作的时间复杂度是O(1),并使用 O(h) 内存,其中 h 是树的高度. 详见:https://leetcode.com/problems/binary-search-tree-iterator/description/ /** * Definition for binary tree * struct TreeNode { *

[LeetCode] Unique Binary Search Trees 独一无二的二叉搜索树

Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For example,Given n = 3, there are a total of 5 unique BST's. 1 3 3 2 1 \ / / / \ 3 2 1 1 3 2 / / \ 2 1 2 3 这道题实际上是Catalan Number卡塔兰数的一个例子,如果对卡塔兰数不熟悉的童鞋可能真不太好做