Leetcode -- 生成由[1 : n]這n個數組成的所有二叉搜索樹

 


二叉搜索樹滿足的條件

  • 當前根節點的值大於左子樹節點的值
  • 當前根節點的值小於右子樹節點的值
  • 左右子樹同樣是二叉搜索樹

1:  找出所有二叉搜索樹的個數

https://leetcode.com/problems/unique-binary-search-trees/description/

https://leetcode-cn.com/problems/unique-binary-search-trees/

給定數值n,計算有多少種不同的二叉搜索樹能夠存儲1,2,...,n這n個數:

 Solution:

example:

n=4,記最終結果爲F(n),   s(4,i)表示總共4個數,以i爲根節點的搜索樹的個數,

從而 F(4) = s(4,1) + s(4,2) + s(4,3) + s(4,4)

對於s(4,1):根節點1的左側爲null,即左子樹的個數爲1, 右側爲由“2 3 4”構成的所有子樹,考慮到 2 3 4構成的所有子樹的個數等於1 2 3構成的所有子樹的個數(都是三個相鄰數),從而s(4,1) = "左子樹的個數" * "右子樹的個數" = 1* F(3) = F(0)*F(3);

對於s(4,2):根節點2的左側爲1,即左子樹的個數爲1, 右側爲由“3 4”構成的所有子樹,考慮到 3 4構成的所有子樹的個數等於1 2 構成的所有子樹的個數(都是2個相鄰數),從而s(4,2) = "左子樹的個數" * "右子樹的個數" = 1* F(2) = F(1)*F(2);

。。。

從而得到:

s(4,1) = F(0)*F(1);

s(4,2) = F(1)*F(2);

s(4,3) = F(2)*F(1);

s(4,4) = F(3)*F(0);

記F(0) =1;F(1) =1;

從而:

F(4) = F(0)*F(3) + F(1)*F(2) + F(2)*F(1) + F(3)*F(0);

       = sum( F(i)*F(3-i) ), i=0,1,2,3

F(n) = sum( F(i)*F(n-1-i) ), i=0,1,2,3,...,n-1

從而遞歸可解,遞歸終止條件是:F(0), F(1)

Code1:超時了

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

		int c = 0;
		for (int i = 0; i <= n - 1; i++)
		{
			c += numTrees(i)*numTrees(n - 1 - i);
		}
		return c;
    }

Code2: 將中間結果保存下來,就像斐波那契數的計算:擊敗了100%用戶

class Solution {
public:
    int numTrees(int n) {
        if (n < 0)
			return 0;
		if (0 == n || 1 == n)
		{
			return 1;
		}
		//store the result to reduce time;
		std::vector<int> vecNum;
		vecNum.push_back(1);//0th
		vecNum.push_back(1);//1th

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

			vecNum.push_back(c);
		}
		return vecNum[n];
    }
};

 

2:  找出所有二叉搜索樹並打印

https://leetcode-cn.com/problems/unique-binary-search-trees-ii/

 

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