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)
}
小编辑器