Leetcode 96. Unique Binary Search Trees

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

For example,
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,那么用从1到n这些数字构造一个二叉查找树有多少种方法?

思路:
自己开始想的是用搜索的方法,即从1到n,尝试以每个数字都作为根节点去构造一个二叉查找树,需要用一个数组来记录当前使用了哪些数字。但是有一个很难处理的地方是需要记录当前这棵树的状态,这样才能确定当前搜索到的数字有几种放置的方法。想了一下,这种搜索的方法时间复杂度非常高,应该是阶乘的级别。
最后想到应该是动态规划的思路,但是没想出来解法,还是看了discuss的答案。n个数字情况下,从1到n每个数字都可以当做根节点,用g(k,n)表示n个数字,以k为根节点生成一个BST的方案个数,用t(n)表示n个数字生成BST的总方案数,则t(n) = g(1,n) + g(2,n) + ... + g(n,n),容易知道t(1) = 1,t(2) = 2。
假如n=4,k=2,则k的左子树只能由1来构造,右子树由3、4来构造,而用3、4构造和用1、2构造的方案数其实是一样的,所以能够得出g(2,4) = t(1) * t(2),即g(k, n) = t(k-1) * t(n-k),由此能够推出t(n) = t(0) * t(n-1) + t(1) * t(n-2) + ... + t(n-1) * t(0),t(0)可设置为1.

public int numTrees(int n) {
    if (n <= 1) {
        return 1;
    }

    int[] nums = new int[n+1];
    nums[0] = 1;
    nums[1] = 1;
    for (int i = 2; i <= n; i++) {
        for (int j = 1; j <= i; j++) {
            nums[i] += nums[j - 1] * nums[i - j];
        }
    }

    return nums[n];
}

你可能感兴趣的:(Leetcode 96. Unique Binary Search Trees)