验证二叉搜索树题目的思路探讨与源码
验证二叉搜索树的题目如下图,该题属于树结构和递归类型的题目,主要考察对于树本身结构的理解和认识,结合二叉搜索树的左右子树进行思考就可以进行求解,因为二叉搜索树的特征就是左子树一定小于当前根节点的值,而右子树一定大于根节点的值。本文的题目作者想到2种方法,第一种方法是递归方法,第二种方法是中序遍历方法。其中第一种方法使用java写、第二种方法使用Python写,当然这可能不是最优的解法,还希望各位大佬给出更快的算法。
本人认为该题目可以使用递归法和中序遍历的方法,首先来说递归方法。我们观察初始情况,当树的当前节点是空的时候,直接返回正确,因为空树也是一棵二叉搜索树。而当每次进入的子树,只要有一棵子树的情况是当前的根节点小于等于左子树的值或是当前的根节点大于等于右子树根节点的值的时候,就直接返回False,而如果是其他情况则继续遍历搜索,所以整体的步骤还是属于一个递归搜索的过程,按照这个思路我们的代码如下:
#喷火龙与水箭龟
class Solution {
public boolean isValidBST(TreeNode root) {
return isCorrect(root,Long.MIN_VALUE,Long.MAX_VALUE);
}
public boolean isCorrect(TreeNode node, long small, long big) {
if (node == null) {
return true;
}
if (node.val <= small || node.val >= big) {
return false;
}
return isCorrect(node.left,small,node.val) && isCorrect(node.right,node.val,big);
}
}
显然,还可以使用中序遍历的方法来进行解决,最开始的准备一个栈和备用值,然后判断当前根节点和栈是否非空,访问的时候,将根节点进行入栈,而将当前根节点的左子树指定为根节点,直到根节点为空的时候,也就是访问到最底层的左子树上的时候,然后开始进行出栈的操作,将当前左子树的根节点抛出并判断当前根节点和之前的备用值谁更大,如果备用值大,则直接返回False,因为这代表的是当前的左子树的值大于当前根节点的值,否则就将备用值更新为当前的根节点值,然后将右子树的值赋予为根节点并继续下一轮判断,直到中序遍历结束。所以根据这个思路就可以写出代码,下面是Python代码部分:
#喷火龙与水箭龟
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
backList=[]
preValue=float('-inf')
while backList or root:
while root:
backList.append(root)
root = root.left
root = backList.pop()
if root.val <= preValue:
return False
preValue = root.val
root = root.right
return True
从结果来说java版本的递归方法还不错,python版本的中序遍历算法速度还可以继续提高,应该是可以进一步提速的,希望朋友们能够多多指教,非常感谢。