Leetcode 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

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

 

  1 /**
  2  * Definition for a binary tree node.
  3  * public class TreeNode {
  4  *     public int val;
  5  *     public TreeNode left;
  6  *     public TreeNode right;
  7  *     public TreeNode(int x) { val = x; }
  8  * }
  9  */
 10 public class Solution {
 11     // idea: BST in order traversal is always sorted
 12     public bool IsValidBST(TreeNode root) {
 13         if (root == null) return true;
 14         
 15         var stack = new Stack<TreeNode>();
 16         TreeNode prior = null;
 17         
 18         while (root != null || stack.Count > 0)
 19         {
 20             while (root != null)
 21             {
 22                 stack.Push(root);
 23                 root = root.left;
 24             }
 25             
 26             root = stack.Pop();
 27             if (prior != null)
 28             {
 29                 if (root.val <= prior.val) return false;
 30             }
 31             prior = root;
 32             root = root.right;
 33         }
 34         
 35         return true;
 36     }
 37     
 38     // idea: BST in order traversal is always sorted
 39     // cons: it changes the tree structure which might be not allowed
 40     public bool IsValidBSTSolution3(TreeNode root) {
 41         if (root == null) return true;
 42         
 43         var stack = new Stack<TreeNode>();
 44         stack.Push(root);
 45         TreeNode prior = null;
 46         
 47         while (stack.Count > 0)
 48         {
 49             var p = stack.Peek();
 50             if (p.left != null)
 51             {
 52                 stack.Push(p.left);
 53                 p.left = null;
 54             }
 55             else
 56             {
 57                 stack.Pop();
 58                 
 59                 if (prior != null)
 60                 {
 61                     if (prior.val >= p.val) return false;
 62                 }
 63                 
 64                 prior = p;
 65                 
 66                 if (p.right != null)
 67                 {
 68                     stack.Push(p.right);
 69                     p.right = null;
 70                 }
 71             }
 72         }
 73         
 74         return true;
 75     }
 76     
 77     
 78     // cons: need to use the tricky min/max boundary
 79     public bool IsValidBSTSolution2(TreeNode root) {
 80         return DFS(root, Int64.MinValue, Int64.MaxValue);
 81     }
 82     
 83     private bool DFS(TreeNode node, long min, long max)
 84     {
 85         if (node == null) return true;
 86         if ((long)node.val <= min || (long)node.val >= max) return false;
 87         
 88         return DFS(node.left, min, (long)node.val) && DFS(node.right, (long)node.val, max);
 89     }
 90     
 91     
 92     // idea: for each node: get the min/max value from left and right tree, and check this node with left/right trees forms a BST
 93     // then recursively do this for all child nodes. To optimize we can cache the min/max value for each node.
 94     // cons: two passes of the tree though even with cache
 95     public bool IsValidBSTSolution1(TreeNode root) {
 96         if (root == null) return true;
 97         
 98         var pair = new long[2] {Int64.MaxValue, Int64.MinValue};
 99         FindMinMax(root.left, pair);
100         if ((long)root.val <= pair[1]) return false;
101         pair = new long[2] {Int64.MaxValue, Int64.MinValue};
102         FindMinMax(root.right, pair);
103         if ((long)root.val >= pair[0]) return false;
104         
105         return IsValidBST(root.left) && IsValidBST(root.right);
106     }
107     
108     private void FindMinMax(TreeNode node, long[] pair)
109     {
110         if (node == null) return;
111         pair[0] = Math.Min(pair[0], (long)node.val);
112         pair[1] = Math.Max(pair[1], (long)node.val);
113         FindMinMax(node.left, pair);
114         FindMinMax(node.right, pair);
115     }
116 }
 
 

/** * Definition for a binary tree node. * public class TreeNode { *     public int val; *     public TreeNode left; *     public TreeNode right; *     public TreeNode(int x) { val = x; } * } */public class Solution {    // idea: BST in order traversal is always sorted    public bool IsValidBST(TreeNode root) {        if (root == null) return true;                var stack = new Stack<TreeNode>();        TreeNode prior = null;                while (root != null || stack.Count > 0)        {            while (root != null)            {                stack.Push(root);                root = root.left;            }                        root = stack.Pop();            if (prior != null)            {                if (root.val <= prior.val) return false;            }            prior = root;            root = root.right;        }                return true;    }        // idea: BST in order traversal is always sorted    // cons: it changes the tree structure which might be not allowed    public bool IsValidBSTSolution3(TreeNode root) {        if (root == null) return true;                var stack = new Stack<TreeNode>();        stack.Push(root);        TreeNode prior = null;                while (stack.Count > 0)        {            var p = stack.Peek();            if (p.left != null)            {                stack.Push(p.left);                p.left = null;            }            else            {                stack.Pop();                                if (prior != null)                {                    if (prior.val >= p.val) return false;                }                                prior = p;                                if (p.right != null)                {                    stack.Push(p.right);                    p.right = null;                }            }        }                return true;    }            // cons: need to use the tricky min/max boundary    public bool IsValidBSTSolution2(TreeNode root) {        return DFS(root, Int64.MinValue, Int64.MaxValue);    }        private bool DFS(TreeNode node, long min, long max)    {        if (node == null) return true;        if ((long)node.val <= min || (long)node.val >= max) return false;                return DFS(node.left, min, (long)node.val) && DFS(node.right, (long)node.val, max);    }            // idea: for each node: get the min/max value from left and right tree, and check this node with left/right trees forms a BST    // then recursively do this for all child nodes. To optimize we can cache the min/max value for each node.    // cons: two passes of the tree though even with cache    public bool IsValidBSTSolution1(TreeNode root) {        if (root == null) return true;                var pair = new long[2] {Int64.MaxValue, Int64.MinValue};        FindMinMax(root.left, pair);        if ((long)root.val <= pair[1]) return false;        pair = new long[2] {Int64.MaxValue, Int64.MinValue};        FindMinMax(root.right, pair);        if ((long)root.val >= pair[0]) return false;                return IsValidBST(root.left) && IsValidBST(root.right);    }        private void FindMinMax(TreeNode node, long[] pair)    {        if (node == null) return;        pair[0] = Math.Min(pair[0], (long)node.val);        pair[1] = Math.Max(pair[1], (long)node.val);        FindMinMax(node.left, pair);        FindMinMax(node.right, pair);    }}

转载于:https://www.cnblogs.com/liangmou/p/7836904.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值