版权声明:本文为博主原创文章,未经博主允许不得转载。有事联系:[email protected] https://blog.csdn.net/qq_17550379/article/details/82315830
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
- 节点的左子树只包含小于当前节点的数。
- 节点的右子树只包含大于当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:
2
/ \
1 3
输出: true
示例 2:
输入:
5
/ \
1 4
/ \
3 6
输出: false
解释: 输入为: [5,1,4,null,null,3,6]。
根节点的值为 5 ,但是其右子节点值为 4 。
解题思路
这个问题和之前的问题Leetcode 110:平衡二叉树(最详细的解法!!!)类似,但是这个问题有一个陷阱,我们参考之前的写法,很容易写出下面这种写法。
class Solution:
def isValidBST(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
if not root:
return True
if root.left and root.left.val >= root.val:
return False
if root.right and root.right.val <= root.val:
return False
return self.isValidBST(root.left) and self.isValidBST(root.right)
上述写法,没有考虑这种情况
10
/ \
5 15
/ \
6 20
这种写法的错误在于没有理清楚子问题
的本质。节点左子树的所有节点都小于当前节点,而不是仅仅左根节点小于root
,对于右子树同理。我们只要对上述写法稍加修改
class Solution:
def _isValidBST(self, root, min_t=float('-inf'), max_t=float('inf')):
if not root:
return True
if min_t < root.val < max_t and self._isValidBST(root.left, min_t, root.val) and self._isValidBST(root.right, root.val, max_t):
return True
return False
def isValidBST(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
return self._isValidBST(root)
这里我更加推荐下面的这种写法
class Solution:
def _isValidBST(self, root, left=None, right=None):
if not root:
return True
if left and left.val >= root.val:
return False
if right and right.val <= root.val:
return False
return self._isValidBST(root.left, left, root) and self._isValidBST(root.right, root, right)
def isValidBST(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
return self._isValidBST(root)
我们同样写出递归版本,我们这里要用到一个很重要的性质。
二分搜索树的中序遍历是一个有序数列
所以我们这里可以使用中序遍历的递归写法解决这个问题。
class Solution:
def isValidBST(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
if not root:
return True
pre = None
stack = list()
while root or stack:
if root:
stack.append(root)
root = root.left
else:
root = stack.pop()
if pre and root.val <= pre.val:
return False
pre = root
root = root.right
return True
我将该问题的其他语言版本添加到了我的GitHub Leetcode
如有问题,希望大家指出!!!