给定一个整数 n,生成所有由 1 … n 为节点所组成的二叉搜索树。
示例:
输入: 3
输出:
[
[1,null,3,2],
[3,2,null,1],
[3,1,null,null,2],
[2,1,3],
[1,null,2,null,3]
]
解释:
以上的输出对应以下 5 种不同结构的二叉搜索树:
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
解题思路
这是之前问题Leetcode 96:不同的二叉搜索树(超详细的解法!!!)的提高。与之相似的问题还有
这种问题,我们首先就是思考递归过程。我们想要知道3
产生的所有二叉树,我们不妨这样思考。
1 2 3
i
以不同的数作为root
,会产生什么样的结果呢?这就由i
左边的数可以构成什么样的二叉搜索树,i
右边的数可以构成什么样的二叉搜索树决定。接着我们就会在i
的左边去找一个左子树root
,在i
的右边去找一个右子树的root
,这就是递归的过程。
for i in range(left, right + 1):
left_nodes = self._generate(left, i - 1)
right_nodes = self._generate(i + 1, right)
for l in left_nodes:
for r in right_nodes:
root = TreeNode(i)
root.left = l
root.right = r
res.append(root)
我们接着思考边界问题。如果left>right
,我们返回[None]
即可。如果n==0
,我们返回list()
即可。
class Solution:
def generateTrees(self, n):
"""
:type n: int
:rtype: List[TreeNode]
"""
if n == 0:
return list()
return self._generateTrees(1, n)
def _generateTrees(self, left, right):
if left > right:
return [None]
res = list()
for i in range(left, right + 1):
left_nodes = self._generateTrees(left, i - 1)
right_nodes = self._generateTrees(i + 1, right)
for left_node in left_nodes:
for right_node in right_nodes:
root = TreeNode(i)
root.left = left_node
root.right = right_node
res.append(root)
return res
同样我们可以通过记忆化搜索的方法优化这个问题。
class Solution:
def generateTrees(self, n):
"""
:type n: int
:rtype: List[TreeNode]
"""
if n == 0:
return list()
mem = dict()
self._generateTrees(1, n, mem)
return mem[(1, n)]
def _generateTrees(self, left, right, mem):
if left > right:
return [None]
if (left, right) in mem:
return mem[(left, right)]
res = list()
for i in range(left, right + 1):
left_nodes = self._generateTrees(left, i - 1, mem)
right_nodes = self._generateTrees(i + 1, right, mem)
for left_node in left_nodes:
for right_node in right_nodes:
root = TreeNode(i)
root.left = left_node
root.right = right_node
res.append(root)
mem[(left, right)] = res
return res
我将该问题的其他语言版本添加到了我的GitHub Leetcode
如有问题,希望大家指出!!!