recursive approach
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
# time O(N) space O(H)
# main idea: find cases that not meet valid criteria at each node
def isValidBST(self, root: TreeNode) -> bool:
return self._traverse(root,float('-inf'),float('inf'))
def _traverse(self,node,lower,upper):
#step1: termination condition
if not node:
return True
#step2: inorder traversal
val = node.val
if not self._traverse(node.left,lower,val):
return False
if not self._traverse(node.right,val,upper):
return False
#step3: set up criteria to be invalidate
if node.val <= lower or node.val >= upper:
return False
return True
iterative approach
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
# time O(N) space O(H)
# main idea: find cases that not meet valid criteria at each node
def isValidBST(self, root: TreeNode) -> bool:
#step1: create a stack, put root, lower, upper into the stack as tuple
stack = [(root,float('-inf'),float('inf'))]
#step2: set up termination condition: stack is empty
while stack:
node, lower, upper = stack.pop()
# edge case: node is None
if not node:
continue
val = node.val
#step3:(inorder traverse) at each node, compare lower and upper, if not meet, return False
if val >= upper or val <= lower:
return False
#step4: push node.right and node.left back to stack
stack.append((node.right,val,upper))
stack.append((node.left,lower,val))
return True
another solution is to do inorder traversal and append node.val to res and then loop the res to check if its in ascending order