# Solution 2
def numTrees(n: int) -> int:
d = dict() # for memoization
# helper will compute the number of possible trees with values between left and right
def helper(left, right):
# if the tuplet (left, right) is already in d, returned the stored value
if (left, right) in d:
return(d[(left, right)])
if left > right:
# if left > right the list of values to add is empty and only 1 None tree can be created
d[(left, right)] = 1 # store the value
return 1
else:
total_trees = 0
# loop on i between left and right where i is the current node value
for i in range(left, right+1):
number_left_subtrees = helper(left, i-1) # number of possible correct subtrees on left branch
number_right_subtrees = helper(i+1, right) # number of possible correct subtrees on right branch
total_trees += number_left_subtrees * number_right_subtrees # add the number of correct subtrees with i a pivot
d[(left, right)] = total_trees # store the value
return(total_trees)
return(helper(1, n))