LintCode-95: Validate Binary Search Tree

  1. Validate Binary Search Tree
    中文English
    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.
A single node tree is a BST
Example
Example 1:
Input: For the following binary tree(only one node):
-1
Output:true

Example 2:
Input: For the following binary tree:

  2
 / \
1   4
   / \
  3   5
	
Output: true

这题有两种解法:
解法1:利用binary search tree <=> 中序遍历为升序序列 这个充要条件。
注意这题条件好像认为bst不存在重复元素,但实际上是可以重复的,而且重复元素(根和子节点值一样的话),子节点放在左边。

代码如下:

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */

class Solution {
public:
    /**
     * @param root: The root of binary tree.
     * @return: True if the binary tree is BST, or false
     */
    TreeNode *lastNode;
    bool isValid;
    
    bool isValidBST(TreeNode * root) {
        lastNode=NULL;
        isValid=true;
        inorderTraversal(root);
        return isValid;
    }
    
    void inorderTraversal(TreeNode *root) {
        if (!root) return;
        inorderTraversal(root->left);
        
        if (lastNode && root->val <= lastNode->val) {
            isValid=false;
            return;            
        } else {
            lastNode=root;
        }
        
        inorderTraversal(root->right);
    }
};

代码2: 分治法。左右两边分别递归。下次再写。

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */
 
 struct ResultType {
     bool isBST;
     TreeNode * minNode, * maxNode;
     ResultType(bool is_bst = true, TreeNode * min_node = NULL, TreeNode * max_node = NULL) : isBST(is_bst), minNode(min_node), maxNode(max_node) {}
 };

class Solution {
public:
    /**
     * @param root: The root of binary tree.
     * @return: True if the binary tree is BST, or false
     */
    bool isValidBST(TreeNode * root) {
        //if (!root) return true;
        //if (!root->left && !root->right) return true;
   
        return helper(root).isBST;
    }
    
private:
    ResultType helper(TreeNode * root) {
        if (!root) return ResultType(true);
        if (!root->left && !root->right) return ResultType(true, root, root);
        
        ResultType left = helper(root->left);
        if (!left.isBST) return ResultType(false);
        
        ResultType right = helper(root->right);
        if (!right.isBST) return ResultType(false);
        
        //now both left and right subtree are BST
        if (left.maxNode && root->val <= left.maxNode->val) return ResultType(false);
        if (right.minNode && root->val >= right.minNode->val) return ResultType(false);
        
        //the tree is already BST, now need to set the minNode and maxNode
        //return ResultType(true, left.minNode, right.maxNode);
        ResultType result = ResultType(true);
        result.minNode = left.minNode ? left.minNode : root;
        result.maxNode = right.maxNode ? right.maxNode : root;
        return result;
    }
};

注意:

  1. 最后返回时应该考虑left.minNode和right.maxNode是否存在,若否,则用root代替。
  2. 下面这一行并不需要。
    if (!root->left && !root->right) return ResultType(true, root, root);
    3)下面这种写法不对。因为没有考虑所有左子树节点的最大值和所有右子树节点的最小值。
    bool isValidBST(TreeNode * root) {
        if (!root) return true;
        if (!root->left && !root->right) return true;
        if (root->left && root->left->val >= root->val) return false;
        if (root->right && root->right->val <= root->val) return false;
        if (isValidBST(root->left) && isValidBST(root->right)) return true;
        return false;
    }

另外总结一个小知识点:
二叉树的分治法是否需要用到Memorization呢?答案是不需要,因为Memorization和分治法的区别是看有没有重复搜索。二叉树在左子树和右子树没有重复。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值