zoukankan      html  css  js  c++  java
  • [LeetCode] 96. Unique Binary Search Trees

    Given n, how many structurally unique BST's (binary search trees) that store values 1 ... n?

    Example:

    Input: 3
    Output: 5
    Explanation:
    Given n = 3, there are a total of 5 unique BST's:
    
       1         3     3      2      1
               /     /      /       
         3     2     1      1   3      2
        /     /                        
       2     1         2                 3

    独一无二的二叉搜索树。题意是给一个数字N,代表有N个node。问这N个节点能组成多少个独一无二的二叉搜索树。这里我参考了喜刷刷的思路。注意既然是组成二叉搜索树,那么也就意味着左子树的节点需要小于根节点,右子树的节点需要大于根节点,而且这里面任何一个节点都可以当做根节点来用。注意到比如题目给的这个例子,N = 3,

    • 当根节点为1的时候,左子树有0个元素(唯一一种情况),右子树有2个元素,而且右子树可以有两种情况(比如第一个树和最后一个树),所以当根节点为1的时候,组成的BST有可能有1 * 2 = 2种情况
    • 当根节点为2的时候,左子树有1个元素(一种情况),右子树有1个元素(一种情况),所以组成的BST有1 * 1 = 1种情况
    • 当根节点为3的时候,左子树有2个元素(两种情况),右子树有0个元素(一种情况),所以组成的BST有2 * 1 = 2种情况

    总计2 + 1 + 2 = 5种情况

    所以才会有这个公式,可以把他记成左边的情况 * 右边的情况

    f(n) = f(0) * f(n-1) + f(1) * f(n-2) + ... + f(n-2) * f(1) + f(n-1) * f(0)

    设dp[n]是最后能用n个node组成的BST的数量/情况。其中base case是dp[1] = 1,i代表可用的节点个数,j代表左子树上可用的节点个数,所以j的范围才是[0, i),因为需要留一个节点当做根节点。当有n个node的时候,需要先选定一个node作为根节点,然后需要算出以这个node为根节点的情况下,左子树可以有几种情况和右子树可以有几种情况。几个base case的结果如下,

    dp[1] = 1, dp[2] = 2, dp[3] = 5, dp[4] = 14

    时间O(n)

    空间O(n)

    Java实现

     1 class Solution {
     2     public int numTrees(int n) {
     3         int[] res = new int[n + 1];
     4         res[0] = 1;
     5         for (int i = 1; i <= n; i++) {
     6             for (int j = 0; j < i; j++) {
     7                 res[i] += res[j] * res[i - 1 - j];
     8             }
     9         }
    10         return res[n];
    11     }
    12 }

    JavaScript实现

     1 /**
     2  * @param {number} n
     3  * @return {number}
     4  */
     5 var numTrees = function (n) {
     6     var res = new Array(n + 1).fill(0);
     7     res[0] = 1;
     8     for (var i = 1; i <= n; i++) {
     9         for (var j = 0; j < i; j++) {
    10             // j代表左子树有几种情况,i - j - 1代表右子树有几种情况
    11             res[i] += res[j] * res[i - j - 1];
    12         }
    13     }
    14     return res[n];
    15 };

    还有一个非常好的discussion

    LeetCode 题目总结

  • 相关阅读:
    有return的情况下try catch finally的执行顺序
    java面试题
    JSTL常用标签
    文件引入路径设置
    JavaScript配合button.onclick()使用总结
    Java NIO vs IO
    如何在Oracle官网下载历史版本JDK
    常量池之String.intern()方法
    MyeclipseJRE版本设置
    JVM常用参数配置
  • 原文地址:https://www.cnblogs.com/cnoodle/p/12290655.html
Copyright © 2011-2022 走看看