LeetCode:95. 不同的二叉搜索树 II
给定一个整数 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
解题思想:
利用『二叉搜索树』的定义,
如果以 i 为根节点,那么其左子树由[1, i - 1]构成,右子树由[i + 1, n] 构成。
要构建包含1到n的二叉搜索树,只需遍历1到n中的数作为根节点
以i为界将数列分为左右两部分,小于i的数作为左子树,大于i的数作为右子树
使用两重循环将左右子树所有可能的组合链接到以 i为根节点的节点上。
以上求解的思路非常适合用递归来处理,接下来便是设计递归的 终止步、输入参数和返回结果
首先可以肯定的是必须使用『数的区间』这两个输入参数,又因为i是随着『数的区间』这两个参数的,
故不应该将其加入到输入参数中。
接下来谈谈终止步的确定,由于根据i拆分左右子树的过程中,递归调用的方法中入口参数会缩小,
且存在start <= i <= end, 故终止步为start > end
定义树结构:
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
递归代码:
from typing import List
class Solution:
def generateTrees(self, n: int) -> List[TreeNode]:
if n==0: return []
def build_Trees(left, right):
all_trees = []
# 终止处
if left > right:
return [None]
for i in range(left, right+1):
left_trees = build_Trees(left, i - 1)
right_trees = build_Trees(i + 1, right)
for l in left_trees:
for r in right_trees:
cur_tree = TreeNode(i)
cur_tree.left = l
cur_tree.right = r
all_trees.append(cur_tree)
return all_trees
res = build_Trees(1, n)
return res
测试代码:
if __name__ =="__main__":
s = Solution()
n = 4
r = s.generateTrees(n)
print(r)