以下是题目要求:
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 3Binary tree
[2,1,3]
, return true.
Example 2:
1 / \ 2 3
Binary tree [1,2,3]
, return false.
大体意思就是给你一个二叉树,让你写一个算法判断它是否是二叉搜索树即(每个节点的左子树的值都比它小,右子树上的值都比它大)。
一.我的解法
因为是验证二叉搜索树,所以很容易想到的是中序遍历的二叉搜索树可以得到一个数值递增的序列。所以用中序遍历的同时检查前后两结点值的大小关系便可以解决了。
class Solution{
TreeNode pre=null;
public boolean isValidBST(TreeNode root){
if(root==null) return true;
return inorder(root);
}
public boolean inorder(TreeNode root){
if(root==null) return true;
if(!inorder(root.left)) return false;
if(pre!=null&&pre.val>=root.val) return false;
pre=root;
return inorder(root.right);
}
}
时间复杂度是O(n)。
需要注意一点的是维护的pre需要是全局变量,否则在inorder方法中改变pre的地址是不会对之前的pre产生影响的。
2.扩展
在LeetCode的discussion的板块中可以发现有很多有意思的其它解法。
1)以先序遍历二叉树,同时检查是否在要求的值域内,虽然用Long.MIN_VALUE和Long.MAX_VALUE是有点buggy,但我觉得是个很聪明的解法,巧妙地利用了题目的bug。时间复杂度也是O(n)。class Solution{
public boolean isValidBST(TreeNode root){
return preorder(root,Long.MIN_VALUE,Long.MAX_VALUE);
}
public boolean preorder(TreeNode root,long min,long max){
if(root==null) return true;
if(root.val>=max||root.val<=min) return false;
return preorder(root.left,min,root.val)&&preorder(root.right,root.val,max);
}
class Solution{
public boolean isValidBST(TreeNode root){
return preorder(root,Long.MIN_VALUE,Long.MAX_VALUE);
}
public boolean preorder(TreeNode root,long min,long max){
if(root==null) return true;
if(root.val>=max||root.val<=min) return false;
return preorder(root.left,min,root.val)&&preorder(root.right,root.val,max);
}
这个是原地址的链接,有兴趣的可以参考一下原地址。
2)用栈实现中序遍历,基本上是用迭代的方式实现了递归。
class Solution {
public boolean isValidBST(TreeNode root) {
if(root==null) return true;
Stack<TreeNode> stack=new Stack<>();
TreeNode pre=null;
while(root!=null||!stack.empty()){
while(root!=null){
stack.push(root);
root=root.left;
}
root=stack.pop();
if(pre!=null&&pre.val>=root.val) return false;
pre=root;
root=root.right;
}
return true;
}
}
参考原地址:
https://discuss.leetcode.com/topic/46016/learn-one-iterative-inorder-traversal-apply-it-to-multiple-tree-questions-java-solution
本人还是个菜鸡,如果有错误的地方请提出,我会积极改进。