验证二叉搜索树
1.三种解法
递归法–利用性质
由二叉搜索树的性质:二叉搜索树的中序遍历是一个递增序列,可以得到一个思路。先用中序遍历遍历一遍这棵树,然后把结果存到一个result数组中,接着判断该数组是不是递增的即可。
def isValidBST(root):
result = []
# 中序遍历
def traversal(root):
if not root:
return
traversal(root.left) # 左
result.append(root.val) # 中
traversal(root.right) # 右
traversal(root)
# 判断是否递增
for i in range(len(result)-1):
if result[i] >= result[i+1]:
return False
return True
递归法–递归遍历的过程中直接判断是否有序
其实这种写法和上面那个方法一样,只不过在把上面方法中的判断是否递增这步放到了每个节点上面。在递归到一个结点的时候:
- 先递归得到他的左子树中的最大值,然后判断该最大值是否比根节点的值小,如果小,则:
- 去递归得到他的右子树中的最小值,如果根节点的值小于这个最小值,则返回True,直到所有节点都被遍历。
其中只要有一个节点不满足上述逻辑,就返回False即可
def isValidBST(self, root: TreeNode) -> bool:
# 规律: BST的中序遍历节点数值是从小到大.
cur_max = -float("INF")
def __isValidBST(root: TreeNode) -> bool:
nonlocal cur_max
if not root:
return True
# 左
# 判断左子树是不是二叉搜索树
is_left_valid = __isValidBST(root.left)
# 中
# 更新cur_max为左子树的最大值或者为右子树的最小值,这个要去自己找个例子一步一步去做才能明白
if cur_max < root.val:
cur_max = root.val
else:
return False
# 右
# 判断右子树是不是二叉搜索树
is_right_valid = __isValidBST(root.right)
# 如果左右子树都是二叉搜索树
return is_left_valid and is_right_valid
return __isValidBST(root)
迭代法–中序遍历
在原来中序遍历迭代法的基础上按照上面递归的想法修改一下即可。
def isValidBST(self, root: TreeNode) -> bool:
stack = []
cur = root
pre = None # 记录当前节点前一个节点
while cur or stack:
if cur: # 指针来访问节点,访问到最底层
stack.append(cur)
cur = cur.left
else: # 逐一处理节点
cur = stack.pop()
if pre and cur.val <= pre.val: # 比较当前节点和前节点的值的大小
return False
pre = cur
cur = cur.right
return True
2.总结
算法
- 二叉搜索树的左子树的所有节点的值都要小于根节点的值,右子树的所有节点的值都要大于根节点的值,而不单单是左子树的根节点和右子树的根节点这两个节点。
- 二叉搜索树的中序遍历是一个递增序列