[路飞]_程序员必刷力扣题: 95. 不同的二叉搜索树 II

133 阅读1分钟

95. 不同的二叉搜索树 II

给你一个整数 n ,请你生成并返回所有由 n 个节点组成且节点值从 1 到 n 互不相同的不同 二叉搜索树 **。可以按 任意顺序 返回答案。

示例 1: image.png

输入:n = 3
输出:[[1,null,2,null,3],[1,null,3,2],[2,1,3],[3,1,null,null,2],[3,2,null,1]]

示例 2:

输入: n = 1
输出: [[1]]

提示:

  • 1 <= n <= 8

递归的思想

思路

二叉搜索树

每个根节点的值都
* 大于左子树的任意一个节点的值
* 小于右子树的任意一个节点的值

所以我们需要考虑根节为不同的值(i)的情况,很明显需要遍历字符串

有了根节点, 左子树的值也能确定了[1,i) 右子树的值也能确定为(i+1,n]

生成左右子树的所有结果,并且双循环,将左右子树的所有可能拼接在根节点上,每个结果push到res中,最后返回res

需要找到左右子树的所有二叉搜索树结果,这里可能发现左右子树会重新回到开始的问题,所以递归调用

当左右子树的区间小于1的时候代表左右子树为空,直接返回[null]

实现过程; 声明递归函数generateChildTrees 参数start:子节点开始的值 参数end:子节点结束的值

  • 如果start大于end则直接返回空数组[null]
  • 开始遍历从start到end
  • 调用generateChildTrees传入(start,i-1)生成左子树的所有结果
  • 调用generateChildTrees传入(i+1,end)生成右子树的所有结果
  • 双循环,以当前值为i值创建根节点分别将左右子树的结果leftTrees[j]和rightTrees[k]拼接在根节点的左右子树上并push到res中

最后返回res即可

var generateTrees = function (n) {
    function generateChildTrees(start, end) {
        var res = []
        if (start > end) {
            return [null]
        }
        for (var i = start; i <= end; i++) {
            var leftTrees = generateChildTrees(start, i - 1)
            var rightTrees = generateChildTrees(i + 1, end)
            for (var j = 0; j < leftTrees.length; j++) {
                for (var k = 0; k < rightTrees.length; k++) {
                    var currTree = new TreeNode(i)
                    currTree.left = leftTrees[j]
                    currTree.right = rightTrees[k]
                    res.push(currTree)
                }
            }
        }

        return res
    }
    return generateChildTrees(1, n)
};