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

  • 相关阅读:
    Swift DispatchQueue
    Function types cannot have argument labels 错误解决方案
    CocoaPods 使用详解
    鸡兔同笼:笼子里一共有鸡和兔子35只,一共有94条退, 笼子里一共有鸡和兔子共多少只
    一次酒店宴席安排宾客就座吃饭,5人一桌剩4人, 7人一桌剩6人,9人一桌剩8人,11人一桌正好。 问宴席共最少有多少人
    一次酒店宴席安排宾客就座吃饭,5人一桌剩4人, 7人一桌剩6人,9人一桌剩8人,11人一桌正好。 问宴席共最少有多少人
    求1到100之间的素数(能被1和他本身整除的数)
    求1到100之间的素数(能被1和他本身整除的数)
    给你一个整型数组如{1,3,4,7,2,1,1,5,2}, * 打印出现次数最多的那个数,如果最多的次数相同,则打印数字大的那个数。
    给你一个整型数组如{1,3,4,7,2,1,1,5,2}, * 打印出现次数最多的那个数,如果最多的次数相同,则打印数字大的那个数。
  • 原文地址:https://www.cnblogs.com/lz87/p/7070953.html
Copyright © 2011-2022 走看看