95. 不同的二叉搜索樹II
給定一個整數 n,求以 1 … n 爲節點組成的二叉搜索樹有多少種?
示例:
輸入: 3
輸出:
[
[1,null,3,2],
[3,2,null,1],
[3,1,null,null,2],
[2,1,3],
[1,null,2,null,3]
]
解釋:
以上的輸出對應以下 5 種不同結構的二叉搜索樹:
正好按照順序,左邊比i小,右邊比i大。
劃分左右子樹,遞歸構造。至於遞歸函數中爲啥都用的是指針,是參考了,若不用指針,全部實例化的話會存在大量的對象拷貝,要調用拷貝構造函數,具體我尚且不太懂,感覺挺言之有理,不明覺厲。
代碼
class Solution {
public:
vector<TreeNode*> generateTrees(int n) {
//vector<TreeNode*>res;
if (n == 0)return{};
return *help(1,n);
}
vector<TreeNode*> *help(int start, int end)
{
vector<TreeNode*> *subTree = new vector<TreeNode*>();
if (start > end)subTree->push_back(NULL);
else
{
for (int i = start; i <= end; i++)
{
vector<TreeNode*> *leftSubTree = help(start, i - 1);
vector<TreeNode*> *rightSubTree = help(i+1,end);
for(int j=0;j<leftSubTree->size();j++)
for (int k = 0; k < rightSubTree->size(); k++)
{
TreeNode *node = new TreeNode(i);
node->left = (*leftSubTree)[j];
node->right = (*rightSubTree)[k];
subTree->push_back(node);
}
}
}
return subTree;
}
};
96. 不同的二叉搜索樹
這道題實際上是 Catalan Number卡塔蘭數的一個例子,如果對卡塔蘭數不熟悉的童鞋可能真不太好做。
分析
就跟斐波那契數列一樣,我們把n = 0 時賦爲1,因爲空樹也算一種二叉搜索樹,那麼n = 1時的情況可以看做是其左子樹個數乘以右子樹的個數,左右字數都是空樹,所以1乘1還是1。那麼n = 2時,由於1和2都可以爲根,分別算出來,再把它們加起來即可。n = 2的情況可由下面式子算出:
dp[2] = dp[0] * dp[1] (1爲根的情況)
+ dp[1] * dp[0] (2爲根的情況)
同理可寫出 n = 3 的計算方法:
dp[3] = dp[0] * dp[2] (1爲根的情況)
+ dp[1] * dp[1] (2爲根的情況)
+ dp[2] * dp[0] (3爲根的情況)
由此可以得出卡塔蘭數列的遞推式爲:
得出卡塔蘭數列的遞推式爲:
代碼
class Solution {
public:
int numTrees(int n) {
if (n <= 0)return 0;
vector<int>dp(n+1, 0);
dp[0] = 1;
dp[1] = 1;
for (int i = 2; i <= n; i++)
{
for (int j = 0; j <= i-1; j++)
dp[i] += dp[j]*dp[i-1 - j];
}
return dp[n];
}
};
[1]http://fisherlei.blogspot.com/2013/03/leetcode-unique-binary-search-trees-ii.html
[2]https://www.cnblogs.com/ariel-dreamland/p/9159691.html