leetcode | 95. Unique Binary Search Trees Ⅱ

题目

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
}

遇到的问题

  1. 递归搜索中没有s>t的判断:
    在这里插入图片描述
    由上图可以看出,如果不加上s>t的判断,则输出数据只有一组[[2,1,3]],对应于题目给出的第四幅二叉树。原因是源程序将只有一个孩子的节点给忽视掉了(当s>t时返回的list为空),所以五组数据中只剩下了一组。
  2. 输入数据为0
    在这里插入图片描述
    当输入数据为0时,我们的输出结果应该为空数组,不应该是空数组的数组。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值