[前端]_一起刷leetcode 95. 不同的二叉搜索树 II

127 阅读3分钟

大家好,我是挨打的阿木木,爱好算法的前端摸鱼老。最近会频繁给大家分享我刷算法题过程中的思路和心得。如果你也是想提高逼格的摸鱼老,欢迎关注我,一起学习。

题目

95. 不同的二叉搜索树 II

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

 

示例 1:

输入: 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

思路

  1. 枚举从1n每个元素作为根节点的情况;
  2. 把剩余元素放到子数中去,大于根元素的放到右子树,小于根元素的放到左子树;
  3. 左右子树一样依次枚举每种可能性,这样子就形成了递归问题;
  4. 递归问题我们可以找状态转移方程,也就是从从1n可以抽离成左边界为1,右边界为n
  5. 下一轮比如根节点为3, 那么左子树的两个边界为13 - 1,右子树的两个边界为3 + 1n;
  6. 最终通过两两组合 也就是左子树的所有可能和右子树的所有可能做个双重for循环枚举即可。

实现

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {number} n
 * @return {TreeNode[]}
 */
var generateTrees = function(n) {
    return createNextNode(1, n);
};

// 生成所有的树节点
function createNextNode(left, right) {
    if (left === right) return [ new TreeNode(left) ];
    let result = [];

    // 枚举每个元素作为根节点的情况
    for (let i = left; i <= right; i++) {
        // 找到所有可能的左右节点的情况
        const leftNode = createNextNode(left, i - 1);
        const rightNode = createNextNode(i + 1, right);

        // 如果没有左节点只有右节点
        if (!leftNode.length) {
            for (let pr = 0; pr < rightNode.length; pr++) {
                const node = new TreeNode(i, null, rightNode[pr]);
                result.push(node);
            }
        }

        // 如果没有右节点只有左节点
        if (!rightNode.length) {
            for (let pl = 0; pl < leftNode.length; pl++) {
                const node = new TreeNode(i, leftNode[pl], null);
                result.push(node);
            }
        }

        // 枚举所有的可能性
        for (let pl = 0; pl < leftNode.length; pl++) {
            for (let pr = 0; pr < rightNode.length; pr++) {
                const node = new TreeNode(i, leftNode[pl], rightNode[pr]);
                result.push(node);
            }
        }
    }

    return result;
}

代码简化

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {number} n
 * @return {TreeNode[]}
 */
var generateTrees = function(n) {
    return createNextNode(1, n);
};

// 生成所有的树节点
function createNextNode(left, right) {
    if (left === right) return [ new TreeNode(left) ];
    let result = [];

    // 枚举每个元素作为根节点的情况
    for (let i = left; i <= right; i++) {
        // 找到所有可能的左右节点的情况
        const leftNode = createNextNode(left, i - 1);
        const rightNode = createNextNode(i + 1, right);

        // 如果没有左节点
        if (!leftNode.length) {
           leftNode.push(null);
        }

        // 如果没有右节点
        if (!rightNode.length) {
            rightNode.push(null);
        }

        // 枚举所有的可能性
        for (let pl = 0; pl < leftNode.length; pl++) {
            for (let pr = 0; pr < rightNode.length; pr++) {
                const node = new TreeNode(i, leftNode[pl], rightNode[pr]);
                result.push(node);
            }
        }
    }

    return result;
}

看懂了的小伙伴可以点个关注、咱们下道题目见。如无意外以后文章都会以这种形式,有好的建议欢迎评论区留言。