方法1: Traverse
corner case: what if there are equal numbers;
in-order traverse. we need to keep a lastNode, which compares to current node, if lastNode != None and lastNode.val >= currentNode.val, return False;
time complexity is O(n), space complexity O(n) since we keep up to the entire tree;
when we use traverse, there is no return value in the dfs method, so we need to keep a global variable by either self.variable or keep in the parameter. here we use global variable;
set initial value as True, change to False and return when it visit a invalid node. if it is False at beginning, it’s hard to determine when to set it to True;
class Solution:
def isValidBST(self, root):
self.isValid = True # set initial value as True, change to False when it visit a invalid node
self.lastNode = None
self.dfs(root)
return self.isValid
def dfs(self, root):
if root is None:
return
self.dfs(root.left)
if self.lastNode is not None and self.lastNode.val >= root.val:
self.isValid = False
return
self.lastNode = root
self.dfs(root.right)
方法2:divide-and-conquer
keep in mind that we need to compare the root with maxleft and minright, not root.left and root.right
class Solution:
def isValidBST(self, root):
_, _, isValid = self.dfs(root)
return isValid
def dfs(self, root):
if root is None:
return None, None, True
leftmin, leftmax, validLeft = self.dfs(root.left)
rightmin, rightmax, validRight = self.dfs(root.right)
if not validLeft or not validRight:
return None, None, False
if leftmax and leftmax.val >= root.val:
return None, None, False
if rightmin and rightmin.val <= root.val:
return None, None, False
minNode = leftmin if leftmin else root # in case no left or no right
maxNode = rightmax if rightmax else root
return minNode, maxNode, True