题目
Given n, how many structurally unique BST’s (binary search trees) that store values 1 … n?
Example:
Input: 3
Output: 5
Explanation:
Given n = 3, there are a total of 5 unique BST's:
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
思路
这道题我自己的思路是一步步递进的。
递归
首先最容易想到的就是递归了。确定好root之后,按照比root小和比root大分到两边,两边的子树就又是一个BST,这样递归是可以解出来的,但是运算重复太多了,到十几就time limit exceed。先贴一下递归的代码:
class Solution:
def numTrees(self, n):
def subtree(head, rear):
sum = 0
if rear <= head:
return 1
else:
for t in range(head, rear+1):
sum += subtree(head, t-1)*subtree(t+1,rear)
return sum
sum = 0
for i in range(1, n+1):
sum += subtree(1, i-1)*subtree(i+1, n)
return sum
递推
因为给的是1-n,所以一旦确定好了root,那么两边都是连续的数字,比如n=11
,取中间数字6作为root,那么左子树1-5和右子树7-11的可能的数量是一样的,因此在递推的时候只需要知道n=1-6
时的可能数量是多少就可以了。我们用storage[n]来存储当有n个数时能够有多少种BST,i
是递推过程中的总数,j
是遍历从1
到(i/2)
,即拿j当作root。
具体见代码:
class Solution:
def numTrees(self, n):
storage = [1, 1, 2]
for i in range(3, n+1):
sum = 0
if i % 2 == 0:
for j in range(1, int(i/2) +1):
sum += storage[j-1] * storage[i-j]
sum *= 2
storage.append(sum)
if i % 2 == 1:
for j in range(1, int((i-1)/2) + 1):
sum += storage[j-1] * storage[i-j]
sum *= 2
sum += storage[int((i-1)/2)] * storage[int((i-1)/2)]
storage.append(sum)
return storage[n]