98. 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.
Example 1:
    2
   / \
  1   3
Binary tree [2,1,3], return true.
Example 2:
    1
   / \
  2   3
BST顺序遍历的结果是一个递增的数组,因此,在遍历每一个子树的时候,子树的值会有一定的范围
 /**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

//这里采用的long型,为了防止验证INT_MAX时出现错误
class Solution {
public:
    bool isValidBST(TreeNode* root) {
        return validate(root, LONG_MIN, LONG_MAX);
    }
private:
    bool validate(TreeNode *r, long min, long max){
        if(r == NULL) return true;

        return min<r->val && r->val < max && validate(r->left, min, r->val) && validate(r->right, r->val, max);


    }
};

上面采用记录最大数值的方法,下面将采用某段区间上的最大节点,最小节点的方法

class Solution {
public:
    bool isValidBST(TreeNode* root) {
        return validate(root, NULL, NULL);
    }
private:
    bool validate(TreeNode *r, TreeNode *minNode, TreeNode *maxNode){
        if(r == NULL) return true;
        if(minNode && minNode->val >= r->val || maxNode && r->val >= maxNode->val )   return false;

        return validate(r->left, minNode, r) && validate(r->right, r, maxNode);
    }
};

下面的方法比较巧妙。

        5
       / \
      3   6
     / \
    1   4

在保证二叉搜索树性质的时候,最重要的是要保证根节点的左子树中的前驱节点(根节点),prev就是用来记录这个节点的。


上述递归的过程为,
      validate(5, prev)(此时prev == NULL)
   (1) /       \(4)
       /         \
    validate(3, prev)(prev == NULL)
(2)  /            \(3)
     /               \
validate(1, prev)  validate(4, prev)

递归的运行过程为:
(1) ->(2)从(1)到(2)的过程中,prev始终为NULL;此时到达valiate(1, prev),接着遍历1的左节点,为空,返回true。此时prev为空,r为1。接下来的过程prev就变成了r,r就是r右子树的前驱。递归返回到validate(3, prev)中的后半部分,


我们会发现prev走过的节点的过程就是一个中序遍历走的节点的过程
NULL  --->  1  --->3  --->4 --->5
class Solution {
public:
    bool isValidBST(TreeNode* root) {
        TreeNode *p = NULL;
        return validate(root, p);
    }
private:    
    //prev记录的是前驱节点
    bool validate(TreeNode *r, TreeNode * & prev){
        if(r == NULL)   return true;

        if(!validate(r->left, prev)) return false;

        //在每次遍历子树的右半边的时候,总能将prev更新到根节点的前驱节点
        if(prev && prev->val >= r->val) return false;
        prev = r;

        return validate(r->right, prev);
    }
};

results matching ""

    No results matching ""