0x00 题目
给你一个整数 n ,请你生成并返回
所有由 n 个节点组成
且节点值从 1 到 n 互不相同的
不同二叉 搜索 树,可以按 任意顺序 返回答案
0x01 思路
二叉搜索树的特征是
根 节点的值
大于 左 子树所有节点的值
小于 右 子树所有节点的值
且 左 子树和 右 子树也同样为二叉 搜索 树
在生成所有可行的二叉 搜索 树的时候
假设当前序列长度为 n 如果枚举根节点的值为 i 那么根据二叉 搜索 树的性质可以知道
左 子树的节点值的集合为 [1 … i−1]右 子树的节点值的集合为 [i+1 … n]
而 左 子树和 右 子树的生成
相较于原问题
是一个序列长度 缩小 的 子 问题
因此可以用 回溯 的方法来解决这道题目
定义 generateTrees(start, end) 函数
表示当前值的集合为 [start,end] 返回序列 [start,end] 生成的所有可行的二叉 搜索 树
按照上面的思路
考虑枚举 [start,end] 中的值 i 为当前二叉搜索树的根
那么序列划分为了 [start, i−1] 和 [i+1, end] 两部分
递归调用这两部分
即 generateTrees(start, i - 1) 和 generateTrees(i + 1, end) 获得所有可行的 左 子树和可行的 右 子树
那么最后一步
只要从可行 左 子树集合中选一棵
再从可行 右 子树集合中选一棵
拼接到 根 节点上
并将生成的二叉搜索树放入答案数组即可
0x02 解法
语言:Swift
树节点:TreeNode
public class TreeNode {
public var val: Int
public var left: TreeNode?
public var right: TreeNode?
public init() { self.val = 0; self.left = nil; self.right = nil; }
public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
self.val = val
self.left = left
self.right = right
}
}解法:
func generateTrees(_ n: Int) -> [TreeNode?] {
// 为 0 时,返回一个空数组
if n == 0 {
return []
}
// 生成序列 [start,end] 的所有可行的二叉 搜索 树
func generateTrees(_ start: Int, _ end: Int) -> [TreeNode?] {
if start > end { return [nil] }
var trees: [TreeNode?] = []
// 依次枚举
for i in start...end {
// 递归生成 左子树集合
let leftTrees = generateTrees(start, i - 1)
// 递归生成 右子树集合
let rightTrees = generateTrees(i + 1, end)
// 从 `左` 子树集合中选一棵
for left in leftTrees {
// 从 `右` 子树集合中选一棵
for right in rightTrees {
// 生成新的二叉搜索树
let cur = TreeNode(i)
cur.left = left
cur.right = right
// 放入结果集
trees.append(cur)
}
}
}
// 最终结果
return trees
}
return generateTrees(1, n)
}小编辑器










