zoukankan      html  css  js  c++  java
  • [LintCode] 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.
    • A single node tree is a BST
    Example

    An example:

      2
     / 
    1   4
       / 
      3   5
    

    The above binary tree is serialized as {2,1,4,#,#,3,5} (in level order).

    Solution 1. In-Order Traversal, O(n) runtime, O(n) space 

    If a binary tree is a BST, then in order traversal returns a list of nodes whose values are strictly increasing. 

     1 /**
     2  * Definition of TreeNode:
     3  * public class TreeNode {
     4  *     public int val;
     5  *     public TreeNode left, right;
     6  *     public TreeNode(int val) {
     7  *         this.val = val;
     8  *         this.left = this.right = null;
     9  *     }
    10  * }
    11  */
    12 public class Solution {
    13     /**
    14      * @param root: The root of binary tree.
    15      * @return: True if the binary tree is BST, or false
    16      */   
    17     public boolean isValidBST(TreeNode root) {
    18         ArrayList<Integer> inOrderList = new ArrayList<Integer>();
    19         isValidBSTHelper(root, inOrderList);
    20         boolean result = true;
    21         if(inOrderList.size() > 1)
    22         {
    23             for(int i = 1; i < inOrderList.size(); i++)
    24             {
    25                 if(inOrderList.get(i - 1) >= inOrderList.get(i))
    26                 {
    27                     result = false;
    28                     break;
    29                 }
    30             }
    31         }
    32         return result;
    33     }
    34     private void isValidBSTHelper(TreeNode root, ArrayList<Integer> inOrderList)
    35     {
    36         if(root != null)
    37         {
    38             isValidBSTHelper(root.left, inOrderList);
    39             inOrderList.add(root.val);
    40             isValidBSTHelper(root.right, inOrderList);
    41         }
    42     }
    43 }

    Solution 2.  Optimization upon solution 1, still using recursion.

    The run time of solution 1 is already BCR, so we consider if space usage can be optimized. 

    Since we only need to check if the given binary tree is a BST or not, we don't need to return 

    all the locations where BST property is violated.  This means we can introduce another parameter

    to the in order traversal helper function that keeps the "just visited" tree node. Each time we visit

    a new node, compare its value with the value of  "just visited" node. If not bigger, we know the 

    given binary tree is not a BST, exit and return false. 

    This optimization saves us from using a O(n) size arraylist. But the worst case recursion space is 

    still O(n).

     1 public class Solution {
     2     private TreeNode prevNode = null;
     3     public boolean isValidBST(TreeNode root) {
     4         return helper(root);    
     5     }
     6     private boolean helper(TreeNode currNode){
     7         if(currNode == null){
     8             return true;
     9         }    
    10         if(!helper(currNode.left)){
    11             return false;
    12         }
    13         if(prevNode != null && prevNode.val >= currNode.val){
    14             return false;
    15         }
    16         prevNode = currNode;
    17         if(!helper(currNode.right)){
    18             return false;
    19         }
    20         return true;
    21     }
    22 }

    Solution 3.  Iterative implementation of solution 2.

     1 public class Solution {
     2     public boolean isValidBST(TreeNode root) {
     3         TreeNode prevNode = null, currNode = root;
     4         Stack<TreeNode> stack = new Stack<TreeNode>();
     5         boolean finished = false;
     6         while(!finished){
     7             while(currNode != null){
     8                 stack.push(currNode);
     9                 currNode = currNode.left;
    10             } 
    11             if(stack.isEmpty()){
    12                 finished = true;
    13             }
    14             else{
    15                 currNode = stack.pop();
    16                 if(prevNode != null && prevNode.val >= currNode.val){
    17                     return false;
    18                 }
    19                 prevNode = currNode;
    20                 currNode = currNode.right;
    21             }
    22         }
    23         return true;
    24     }
    25 }

    Solution 4. Divide and Conquer, O(n) runtime and O(1) space, if not considering recursion space usage.

    Key idea here is that to maintain a BST property for a given node, the following 2 properties must be true

    1. Its left subtree and right subtree must be BST;

    2. Its value must be bigger than the max value of its left subtree and smaller than the min value of its right subtree.

     1 class ResultType {
     2     boolean is_bst;
     3     int maxValue, minValue;
     4     
     5     ResultType(boolean is_bst, int maxValue, int minValue) {
     6         this.is_bst = is_bst;
     7         this.maxValue = maxValue;
     8         this.minValue = minValue;
     9     }
    10 }
    11 
    12 public class Solution {
    13     public boolean isValidBST(TreeNode root) {
    14         ResultType r = validateHelper(root);
    15         return r.is_bst;
    16     }
    17     
    18     private ResultType validateHelper(TreeNode root) {
    19         if (root == null) {
    20             return new ResultType(true, Integer.MIN_VALUE, Integer.MAX_VALUE);
    21         }
    22         
    23         ResultType left = validateHelper(root.left);
    24         ResultType right = validateHelper(root.right);
    25         
    26         if (!left.is_bst || !right.is_bst) {
    27             // if is_bst is false then minValue and maxValue are useless
    28             return new ResultType(false, 0, 0);
    29         }
    30         
    31         if (root.left != null && left.maxValue >= root.val || 
    32               root.right != null && right.minValue <= root.val) {
    33             return new ResultType(false, 0, 0);
    34         }
    35         
    36         return new ResultType(true,
    37                               Math.max(root.val, right.maxValue),
    38                               Math.min(root.val, left.minValue));
    39     }
    40 }

    Related Problems

    Balanced Binary Tree

    Inorder Successor in Binary Search Tree

    Binary Tree Inorder Traversal

    Binary Tree Preorder Traversal

    Binary Tree Postorder Traversal

  • 相关阅读:
    BZOJ 3158: 千钧一发
    BZOJ 1677: [Usaco2005 Jan]Sumsets 求和
    BZOJ 1574: [Usaco2009 Jan]地震损坏Damage
    BZOJ 1644: [Usaco2007 Oct]Obstacle Course 障碍训练课
    BZOJ 1715: [Usaco2006 Dec]Wormholes 虫洞
    BZOJ 1634: [Usaco2007 Jan]Protecting the Flowers 护花
    Vijos P1740聪明的质检员
    Vijos P1680距离
    Vijos P1067Warcraft III 守望者的烦恼
    BZOJ 1385: [Baltic2000]Division expression
  • 原文地址:https://www.cnblogs.com/lz87/p/7070953.html
Copyright © 2011-2022 走看看