• 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
    }
    
  • 相关阅读:
    模拟_大数字符串(HDU_2054)
    DP_字串匹配(HDU_1501)
    动态字典树_字串标记查找+大数(HDU_4099)
    动态字典树_字串查找匹配(HDU_1075)
    动态字典树+DFS(HDU_1298)
    动态字典树_拆分查找(HDU_1247)
    动态字典树_统计前缀子串(HDU_1251)
    动态字典树_统计子串(HDU_2846)
    字典树讲解
    HTML5语义标签的实践(blog页面)
  • 原文地址:https://www.cnblogs.com/autumn-starrysky/p/13354233.html
Copyright © 2020-2023  润新知