LeetCode_Unique Binary Search Trees

一.題目

Unique Binary Search Trees

  Total Accepted: 51771 Total Submissions: 143861My Submissions

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

Show Tags
Have you met this question in a real interview?  
Yes
 
No

Discuss












二.解題技巧

    對於二叉查找樹來說,對於一個結點而言,其左子樹的上所有結點的值都是小於該結點的,其右子樹上所有結點的值都是大於該結點的。因此,由於輸入的數組的值爲1,2,3,...,n,因此,對於數值k而言,其左子樹的結點的個數爲k-1個,右子樹的結點的個數爲n-k個,因此當數值爲k的結點作爲父結點時,二叉查找樹的個數a(k)=a(k-1)*a(n-k)。因此,可以通過遞歸調用來計算a(k)的值。因此,含有n個數的數組所能形成的二叉查找樹的個數爲s(n)=a(1)+a(2)+a(3)+...+a(n)。
    從上面的計算方式可以看出,對於每一個a(k)都會被用到多次,因此,可以考慮將這些值用一個表保存下來,這樣,下一次使用的時候就是一個查表的過程,而不是計算的過程,這樣就可以用空間來換的計算時間上面的提升。這個也就是使用動態規劃思想來解決這個問題。
    上面的方法的空間複雜度爲O(n),時間複雜度爲O(n^2)。


三.實現代碼

#include <unordered_map>

using std::unordered_map;

class Solution
{
private:
    unordered_map<int, int> PreResult;
public:
    int numTrees(int n)
    {
        if (n == 0)
        {
            PreResult[0] = 1;
            return 1;
        }

        if (n == 1)
        {
            PreResult[1] = 1;
            return 1;
        }

        if (PreResult.find(n) != PreResult.end())
        {
            return PreResult[n];
        }

        int Result = 0;
        for (int HeadIndex = 1; HeadIndex <= n; HeadIndex++)
        {
            int LeftChildResult = numTrees(HeadIndex - 1);
            int RightChildResult = numTrees(n - HeadIndex);
            Result += LeftChildResult * RightChildResult;
        }

        PreResult[n] = Result;
        return Result;
    }
};




四.體會

    這道題在考慮二叉查找樹的性質的同時,也考慮到使用動態規劃來利用空間換時間,這是一道比較有趣的題,同時考察了兩個方面的知識。



版權所有,歡迎轉載,轉載請註明出處,謝謝微笑





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章