首页 > 代码库 > LeetCode之Unique Binary Search Trees

LeetCode之Unique Binary Search Trees

毕业快一年了,算法相关的知识也快忘了差不多了。工作过程中,产品知识最重要,其次是代码的设计。算法的重要性几乎体现不出来。

最近忙里偷闲,在LeetCode OJ上闲逛, 打算把AC Rate >= 30%的题先A掉。

Unique Binary Search Trees 这道题AC非常高,题目是这样的,

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

直觉上应该用递归,或者是动态规划。

下面是思路:

设U(1, 2, ..., n)代表存储1...n的binary search tree的数目。dp(i, n-1)代表以i为根,包含n-1个子结点的二叉树数目。
        U(1, 2, ..., n) = dp(1, n-1) + dp(2, n-1) + ... dp(n, n-1).
        Clearly, dp(i, n-1) = U(1, 2, ..., i-1) * U(i+1, i+2, ..., n), 

and U(i+1, i+2, ..., n) = U(1, 2, ..., n-i).
        Thus, dp(i, n-1) = U(1, 2, ..., i-1) * U(1, 2, ..., n-i).
        
        不妨简记U(n) = U(1, 2, ..., n), 那么
        U(n) = U(0)*U(n-1) + U(1)*U(n-2) + ... + U(i-1)*U(n-i) + ... + U(n-1)*U(0),  1 <= i <=n.
        
 Example.
        U(0) = 1
        U(1) = 1
        U(2) = dp(1, 1)+dp(2, 1) = U(0)*U(1) + U(1)*U(0) = 2
        U(3) = dp(1, 2)+dp(2, 2)+dp(3, 2) = U(0)*U(2) + U(1)*U(1) + U(2)*U(0) = 2 + 1 + 2 = 5

代码如下:

int rNumTrees(int n, int *U, int len)
    {
        if(U[n] != -1)return U[n];
        
        U[n] = 0;
        for(int i = 1; i <= n; ++i)
            U[n] += rNumTrees(i-1, U, len) * rNumTrees(n-i, U, len);
            
        return U[n];
    }
    

    int numTrees(int n) {
        if(n == 0 || n == 1)return 1;
        
        int *U = new int[n+1];
        memset(U, -1, sizeof(int)*(n+1));
        U[0] = U[1] = 1;
        
        int res = rNumTrees(n, U, n+1);
        delete []U;
        return res;
    }