LeetCode第二天:95、不同的二叉搜索树

133 阅读2分钟

一、概念

1. 什么是二叉搜索树?

二叉搜索树又叫做二叉查找树,二叉排序树,每个节点有两个子节点。

2. 二叉搜索树的特点是什么?

特点是根节点的值大于左子树的值,根节点的值小于右子树的值,左右子树也满足同样性质,注意大小的比较都是为非空的时候

3. 二叉搜索树有哪些应用场景?

在特定的检索条件下,检索效率高。

二、题目

image.png

三、解题

1. 思路分析

  • 在不懂各种方法的时候,从结果倒推,返回的是一颗有n个节点的二叉搜索树
  • 满足二叉搜索树的性质
  • 定义一个根节点的值 i 满足输入结果 n 中,那么这个根节点的左子树的节点满足 [1, i - 1],右子树的节点满足 [i + 1, n],同理这个左子树和右子树一样满足以上条件,可以看出是一个递归。
  • 那么找到递归的出口 当n<1的时候 返回空。
  • 定义一个生成树的函数 generateTree(start, end) 可以生成出满足条件的左子树和右子树,拿着左子树的一个值,拼接上一个右子树的值,拼上根节点就是一个完整的二叉搜索树。
  • 同时如果start > end的时候返回空

2. 代码输出

// 树的定义
function TreeNode(val, left, right) {
    this.val = (val===undefined ? 0 : val)
    this.left = (left===undefined ? null : left)
    this.right = (right===undefined ? null : right)
}
function generateTreeList(n){
    // 递归的出口
    if(n < 1) return []
    return generateTree(1, n)
}
function generateTree(start, end){
    // 定义treelist 
    let treeList = []
    // 如果左边 > 右边拼接上null
    if(start > end) {
        treeList.push(null)
    }
    // 循环开启,从start 到end结束
    for (let i = start; i <= end; i++ ){
        // 可以得到左子树的集合
        let left = generateTree(start, i - 1)
        let right = generateTree(i + 1, end)
        // 抽取左子树和右子树的点拼接根节点
        for(let l of left){
            for(let r of right){
                const tree = new TreeNode(i)
                tree.left = l
                tree.right = r
                // 拼接到结果
                treeList.push(tree)
            }
        }
    }
    return treeList
}

3. 思路回顾

  • 要根据性质来整理条件 左节点 < 根节点 < 右节点
  • 要能找到相同的条件,知道什么时候用递归,什么时候用其它。
  • 有时候难理解的是为什么要循环,其实想想树的遍历基本上怎么都要循环树,无非就是循环的时候会做一些额外的事情。
温故而知新