98. Validate Binary Search Tree

https://leetcode.com/problems/validate-binary-search-tree/#/description

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

Binary tree [1,2,3], return false.

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

Binary tree [1,2,3], return false.

Sol 1 :

Here is a simple solution- If a tree is a binary search tree, then traversing the tree inorder should lead to sorted order of the values in the tree. So, we can perform an inorder traversal and check whether the node values are sorted or not.

# Definition for a binary tree node.
class TreeNode(object):
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None


class Solution(object):

    
    def inorder(self, root, output):
        if root != None:
            self.inorder(root.left, output)
            output.append(root.val)
            self.inorder(root.right, output)
    
    
    def isValidBST(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        output = []
        self.inorder(root, output)
        for i in range(1, len(output)):
            if output[i-1] >= output[i]:
                return False
        return True 


This is the modification of the following code:

https://github.com/Premiumlab/Python-for-Algorithms--Data-Structures--and-Interviews/blob/master/Trees/Trees%20Interview%20Problems%20-%20SOLUTIONS/Binary%20Search%20Tree%20Check%20-%20SOLUTION.ipynb

tree_vals = []

def inorder(tree):
    if tree != None:
        inorder(tree.getLeftChild())
        tree_vals.append(tree.getRootVal())
        inorder(tree.getRightChild())
        
def sort_check(tree_vals):
    return tree_vals == sorted(tree_vals)

inorder(tree)
sort_check(tree_vals)

However, besides the "function/method" issue, other problems about this code emerge when applying the exact codes to Leetcode.

1 This code does not pass values between def inorder and def isValisBST

2 the "tree_vals == sorted(tree_vals)" mishandles the input [1,1]. i.e. If two identical nodes are entered, then sort_check function will return True, it is BST. However, as a matter of fact, two identical nodes are not BST.

Sol 2:

Another classic solution is to keep track of the minimum and maximum values a node can take. And at each node we will check whether its value is between the min and max values it’s allowed to take. The root can take any value between negative infinity and positive infinity. At any node, its left child should be smaller than or equal than its own value, and similarly the right child should be larger than or equal to. So during recursion, we send the current value as the new max to our left child and send the min as it is without changing. And to the right child, we send the current value as the new min and send the max without changing.

# Definition for a binary tree node.
class TreeNode(object):
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None


class Solution(object):
    def isValidBST(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        
        def valid(node, lower, upper):
            if not node:
                return True
            if lower is not None and node.val <= lower:
                return False
            if upper is not None and node.val >= upper:
                return False
            return valid(node.left, lower, node.val) and valid(node.right, node.val, upper)
        
        
    return valid(root, None, None)
原文地址:https://www.cnblogs.com/prmlab/p/7140679.html