leetcode每日一题(2020-07-21):95. 不同的二叉搜索树 II

Posted autumn-starrysky

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode每日一题(2020-07-21):95. 不同的二叉搜索树 II相关的知识,希望对你有一定的参考价值。

题目描述:
给定一个整数 n,生成所有由 1 ... n 为节点所组成的 二叉搜索树 。
技术图片

今日学习:
1.递归

题解:
1.前两天做了96题是只要求输出数量,动规轻轻松松,就没看递归的题解,今天一思考动规的话太复杂了,临时想的递归,思路对了没实现好
2.3.和我的思路一致,实现方式稍有不同
4.记忆化递归
5.动规(果然复杂)

/**
 * 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[]}
 */
// 初步思路,遍历数字,左右建树,暂告失败【不用把节点传进creatTree去,传数字就行了】
var generateTrees = function(n) {
    const nodes = new Array(n)
    for(let i = 0; i < n; i++) {
        let node = new TreeNode(i + 1)
        nodes.push(node)
    }
    function creatTree(nodes) {
        if(nodes.length == 0) return [null]
        if(nodes.length == 1) return [nodes[0]]
        let C = [1, 1, 2, 5, 14, 42, 132, 429, 1430]
        const res = new Array(C[nodes.length])
        for(let i = 0; i < nodes.length; i++) {
            let left = creatTree(nodes.slice(0, i))
            let right = creatTree(nodes.slice(i + 1))
            if(left.length && right.length){
                for(let j = 0; j < left.length; j++) {
                    for(let k = 0; k < right.length; k++) {
                        let temp = nodes[i]
                        nodes[i].left = left[j]
                        nodes[i].right = right[k]
                        res.push(nodes[i])
                        nodes[i] = temp
                    }
                }
            }else if(left.length && !right.length) {
                for(let j = 0; j < left.length; j++) {
                    let temp = nodes[i]
                    nodes[i].left = left[j]
                    res.push(nodes[i])
                    nodes[i] = temp
                }
            }else if(!left.length && right.length) {
                for(let k = 0; k < right.length; k++) {
                    let temp = nodes[i]
                    nodes[i].right = right[k]
                    res.push(nodes[i])
                    nodes[i] = temp
                }
            }
        }
        return res
    }
    return creatTree(nodes)
};
// 思路同上,但是给生成树函数的参数是数字数组而不是节点数组
var generateTrees = function(n) {
    const nArr = new Array(n)
    for(let i = 0; i < n; i++) {
        nArr[i] = i + 1
    }
    const buildTreeArr = (arr) => {
        //0,1,2三种特殊情况特殊考虑
        let treeArr = [], t = new TreeNode();
        if (!arr.length) {
            return [];
        } else if (arr.length === 1) {
            t.val = arr[0];
            treeArr.push(t);
            return treeArr;
        } else if (arr.length === 2) {
            t.val = arr[1];
            t.left = new TreeNode(arr[0]);
            treeArr.push(t);
            t = new TreeNode(arr[0]);
            t.right = new TreeNode(arr[1]);
            treeArr.push(t);
            return treeArr;
        }
        arr.forEach((val, idx, array) => {
            let leftTreeArr = buildTreeArr(array.slice(0, idx));
            let rightTreeArr = buildTreeArr(array.slice(idx + 1, array.length));

            if (leftTreeArr.length && rightTreeArr.length) {
                leftTreeArr.forEach(leftNode => {
                    rightTreeArr.forEach(rightNode => {
                        t = new TreeNode(val);
                        if (leftNode) t.left = leftNode;
                        if (rightNode) t.right = rightNode;
                        treeArr.push(t);
                    })
                });
            } else if (leftTreeArr.length && !rightTreeArr.length) {
                leftTreeArr.forEach(leftNode => {
                    t = new TreeNode(val);
                    if (leftNode) t.left = leftNode;
                    treeArr.push(t);
                });
            } else if (!leftTreeArr.length && rightTreeArr.length) {
                rightTreeArr.forEach(rightNode => {
                    t = new TreeNode(val);
                    if (rightNode) t.right = rightNode;
                    treeArr.push(t);
                });
            }
        })
        return treeArr;
    }
    return buildTreeArr(nArr);
};
// 思路还是差不多,但是不需要传数组,因为紧邻有序,所以只传数组的首末数字就行了
var generateTrees = function (n) {
  function buildTree(start, end) {
    let ans = [];
    if (start > end) return [null];
    for (let i = start; i <= end; i++) {
      let leftNodes = buildTree(start, i - 1);
      let rightNodes = buildTree(i + 1, end);
      for (const leftNode of leftNodes) {
        for (const rightNode of rightNodes) {
          let cur = new TreeNode(i);
          cur.left = leftNode;
          cur.right = rightNode;
          ans.push(cur);
        }
      }
    }
    return ans;
  }
  if (n === 0) return [];
  return buildTree(1, n);
};
//天使爆破组的记忆化递归
const generateTrees = (n) => {
  if (n == 0) return [];
  const memo = new Array(n + 1);
  for (let i = 0; i < memo.length; i++) {
    memo[i] = new Array(n + 1);
  }
  const getAllBSTs = (low, high) => {
    if (low > high) return [null];
    if (memo[low][high]) return memo[low][high];
    if (low == high) return [new TreeNode(low)];
    const res = [];
    for (let i = low; i <= high; i++) {
      const leftBSTs = getAllBSTs(low, i - 1);
      const rightBSTs = getAllBSTs(i + 1, high);
      for (const leftBST of leftBSTs) {
        for (const rightBST of rightBSTs) {
          const root = new TreeNode(i);
          root.left = leftBST;
          root.right = rightBST;
          res.push(root);
        }
      }
    }
    return memo[low][high] = res;;
  };
  return getAllBSTs(1, n);
};
//动规https://leetcode-cn.com/problems/unique-binary-search-trees-ii/solution/si-lu-gen-bu-tong-shu-1chai-bu-duo-jiu-shi-xie-qi-/
var generateTrees = function(n) {
    if(n == 0) return []
    let DP = new Array(n+1)
    DP[0] = [null]
    DP[1] = [new TreeNode(1)]
    
    if(n < 2) return DP[n]

    for(let i = 2; i <= n; i++) {
        DP[i] = []
        for(let j = 0; j < i; j++) {
            DP[j].forEach(ele => {
                DP[i - j - 1].forEach(ele2 => {
                    DP[i].push(getNewBTS(ele,ele2,j))
                })
            })
        }
    }
    return DP[n]
};
function getNewBTS(left, right, leftCount) {
    let newNode = new TreeNode(leftCount + 1)

    newNode.left = treeCopy(left)
    newNode.right = traversalAddTree(newNode.val, treeCopy(right))

    return newNode
}
function treeCopy(node) {
    if(node == null) return null
    let newNode = new TreeNode(node.val)

    newNode.left = treeCopy(node.left)
    newNode.right = treeCopy(node.right)

    return newNode
}
function traversalAddTree(val, node) {
    if(node == null) return null
    node.val = node.val + val
    traversalAddTree(val, node.left)
    traversalAddTree(val, node.right)
    return node
}







以上是关于leetcode每日一题(2020-07-21):95. 不同的二叉搜索树 II的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode每日一题(3)

LeetCode每日一题

LeetCode2022 7月 每日一题

LeetCode2022 7月 每日一题

LeetCode9月 每日一题

LeetCode9月 每日一题