【LeetCode】96. 不同的二叉搜索樹

思路

個人的一些思考:
看完別人提供給的解題思路,對這道題目自己一開始的想法是,把所有的BST樹的組合統計出來,而看到下面的解法,感覺並沒有利用到題目中提到的BST的特性,主要是通過卡特蘭數公式進行了求解

在這裏插入圖片描述
參考自靈魂畫手的題解

下面是自己關於上述的解釋
過程:
1、要獲得以當前值爲根節點的二叉樹個數,如果知道了左子樹和右子樹的二叉樹種類數 ,那我當前的結果只需要把左右子樹的二叉樹種類相乘即可。
因此,假設函數** f(i)** 表示以節點n爲根的二叉搜索樹的個數

2、爲了表達f(),我們需要定義n個節點擁有二叉搜索樹的個數的函數,因此,假設這個函數爲G(n),則可以知道G(n) = f(1)+f(2)+…+f(n),即等於以任何一個節點爲根節點的二叉搜索樹的個數和

3、同樣的,當i爲根節點時,我們可以推導到,左子樹節點個數爲i-1個,則其擁有二叉搜索樹的個數爲G(i-1)右子樹節點個數爲n-i,則其擁有二叉搜索樹的個數爲G(n-i)。則以i爲根節點的二叉搜索樹的個數爲f(i) = 左子樹的二叉樹的種類數目 * 右子樹的二叉樹的種類數目,即f(i) = G(i-1)*G(n-i)

4、可以發現這個轉移方程是兩步進行的,合並可以得到關於G的最終的動態轉移方程
G(n) = G(0)G(n-1)+G(1)G(n-1)+G(2)G(n-2)…+G(n-1)G(0);

該公式稱之爲卡特蘭數
而初始值爲dp[0]=0,dp[1]=1。

5、因此,實現代碼需要對長度爲n的數組的每一個節點進行遍歷,使其爲根節點,其次是遍歷子樹的長度,合併結果,最終的dp[n]即爲我們要求的結果。

代碼

class Solution {
public:
	int numTrees(int n) {
		vector<int> dp(n + 1);
		//初始值
		dp[0] = 1;
		dp[1] = 1;
		for (int i=2;i<n+1;i++)
		{
			for (int j=1;j<i+1;j++)
			{
				//狀態轉移
				//卡特蘭數公式
				dp[i] += dp[j - 1] * dp[i - j];
			}
		}
		return dp[n];
	}
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章