二叉搜索樹滿足的條件
- 當前根節點的值大於左子樹節點的值
- 當前根節點的值小於右子樹節點的值
- 左右子樹同樣是二叉搜索樹
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/