LeetCode 解题报告 (95,96)-- 构造二叉搜索树
两个题目均是要求利用给出的整数 [1, n] 构造出所有的二叉搜索树(BST),其中 95. Unique Binary Search Trees II要求返回所有的二叉树的根节点,96. Unique Binary Search Trees则仅要求返回所有二叉树的数目。
两个题目均可以通过递归实现,思路如下: 1)遍历 [1,n] 中每个整数,并将正在遍历的整数 i 设为根节点 2)将 [1,i-1] 的整数构建出来的子树作为整数 i 构建的根节点的左子树,将 [i+1,n] 的整数构造出来的子树作为整数 i 构建的根节点的右子树 3)对得到的左右子树进行组合,这样便可得到以整数 i 为根节点的所有二叉树
因此,95. Unique Binary Search Trees II实现代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def generateTrees(self, n):
"""
:type n: int
:rtype: List[TreeNode]
"""
if n==0: return []
return self.helper(1, n)
def helper(self,begin,end):
if begin > end:
return [None]
if begin == end:
return [TreeNode(begin)]
result = []
for i in xrange(begin,end+1):
tmp = []
left = self.helper(begin, i-1)
right = self.helper(i+1, end)
for m in left:
for n in right:
root = TreeNode(i)
root.left, root.right = m, n
result.append(root)
return result
96. Unique Binary Search Trees 的解决思路类似于上面提到的递归的方法,只是这道题目仅仅要求返回二叉树的数量。因此可以通过一个技巧缩短计算量,这个技巧就是整数 i 作为根节点和整数 n-i 作为根节点的时候,两者构造的二叉树的数目是一样的。因此整数 i 作为根节点的左右子树的节点数目与整数 n-i 作为根节点的左右子树的节点数目对称相等。
实现的代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def numTrees(self, n):
"""
:type n: int
:rtype: int
"""
result = 0
if n<=1:
return 1
for i in xrange(n/2):
left = self.numTrees(i)
right = self.numTrees(n-i-1)
result += left * right
result *= 2
if n%2 == 1:
result += pow(self.numTrees(n/2),2)
return result
从上面也可以衍生出动态规划的解法,令 dp [m] 表示 m 个节点能够构造的二叉树的数目。那么 dp [m+1] 的计算方法如下1
2for i in xrange(0, m+1):
dp[m+1] += dp[i]*dp[m+1-i-1]
实现的代码如下:1
2
3
4
5
6
7
8
9
10
11
12class Solution(object):
def numTrees(self, n):
"""
:type n: int
:rtype: int
"""
dp = [0 for i in xrange(n+1)]
dp[0],dp[1] = 1, 1
for i in xrange(2,n+1):
for j in xrange(i):
dp[i] += dp[j]*dp[i-j-1]
return dp[n]