给定一个二叉树,判断它是否是合法的二叉查找树(BST)
一棵BST定义为:
节点的左子树中的值要严格小于该节点的值。
节点的右子树中的值要严格大于该节点的值。
左右子树也必须是二叉查找树。
一个节点的树也是二叉查找树。
两种解法:
递归
class Solution(object):
def isValidBST(self, root, left=float("-inf"), right=float("inf")):
"""
当当前判断的节点在左边时,它应该比右上的父亲小,当当前判断的节点在右边时,它应该比左上的父亲大,否则返回False。
如果到叶子节点都未返回False的话,那么就全部合法,返回True即可
:type root: TreeNode
:rtype: bool
"""
if not root:
return True
if root.val >= right or root.val <= left:
return False
return self.isValidBST(root.left, left, min(right, root.val)) \
and self.isValidBST(root.right, max(left, root.val), right)
迭代
class Solution(object):
def isValidBST(self, root):
"""
迭代方式,定义跟节点及其节点应该对应的值范围,初始值范围设为[float('-inf'), float('inf')]
左侧节点取 min(父节点的值,上次范围大值)
右侧节点取 max(上次范围小值,父节点的值)
循环到当前节点只需要判断是否在此范围内即可
见下示例:中间中括号里的为树节点元素,左右为定义的合法范围
比如3下左节点1,它的范围右侧的值就是 min(inf, 3)
比如3下右节点5,它的范围左侧的值就是 max(-inf, 3)
-inf <[3]< inf
/ \
/ \
/ \
-inf <[1]< 3 3 <[5]< inf
/ \ / \
/ \ / \
/ \ / \
-inf<[0]<1 1<[2]<3 3<[4]<5 5<[6]<inf
:param root:
:return:
"""
if not root:
return True
p = [[root,float('-inf'), float('inf')]]
while len(p) > 0:
tmp = p.pop(0)
node = tmp[0]
less = tmp[1]
larger = tmp[2]
if less < node.val < larger:
pass
else:
return False
if node.left:
p.append([node.left, less, min(node.val, larger)])
if node.right:
p.append([node.right, max(less, node.val), larger])
return True