题目
Given an integer n, generate all structurally unique BST’s (binary search trees) that store values 1 … n.
Example:
Input: 3
Output:
[
[1,null,3,2],
[3,2,null,1],
[3,1,null,null,2],
[2,1,3],
[1,null,2,null,3]
]
Explanation:
The above output corresponds to the 5 unique BST's shown below:
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
思路与解法
题目的意思很明确:给定输入数据n,让我们输出所有的存储1-n的二叉搜索树。
我们知道二叉树由左子树、右子树以及一个根节点组成,二叉搜索树则额外满足了左子树上所有节点数值比根节点要小,右子树上所有节点数之比根节点要大。所以,假设i
为根节点,则1~i-1
节点构成左子树,i+1~n
构成右子树。可以采用递归的思想,递归生成左子树、右子树,然后与根节点一同构成一颗完整的二叉搜索树。
代码实现
go语言实现如下:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func generateTrees(n int) []*TreeNode {
if n == 0 {
return []*TreeNode{}
}
return findTrees(1, n)
}
// 函数findTrees,寻找以s~t节点构成的树,返回值为[]*TreeNode,因为这样的树并不止一颗
func findTrees(s int,t int) []*TreeNode {
list := make([]*TreeNode, 0)
// 当s>t,表示搜索到某个节点只有一个孩子的情况,则给list加上nil
if s>t {
list = append(list, nil)
return list
}
// 当s==t,表示搜索到叶子节点,则list加上叶子节点
if s==t {
list = append(list, &TreeNode{s, nil, nil})
return list
}
// 以i为根节点,分别搜索左子树、右子树
for i:=s; i<=t; i++ {
leftNodes := findTrees(s, i-1)
rightNodes := findTrees(i+1, t)
// 将所有左、右子树的组合情况,构成所有可能的二叉搜索树加上list中
for _, leftNode := range leftNodes {
for _, rightNode := range rightNodes {
root := &TreeNode{i, leftNode, rightNode}
list = append(list, root)
}
}
}
// 搜索结束,返回list
return list
}
遇到的问题
- 递归搜索中没有
s>t
的判断:
由上图可以看出,如果不加上s>t
的判断,则输出数据只有一组[[2,1,3]]
,对应于题目给出的第四幅二叉树。原因是源程序将只有一个孩子的节点给忽视掉了(当s>t
时返回的list为空),所以五组数据中只剩下了一组。 - 输入数据为0
当输入数据为0时,我们的输出结果应该为空数组,不应该是空数组的数组。