Leetcode 96. 不同的二叉搜索樹
問題描述
給定一個整數 n,求以 1 … n 爲節點組成的二叉搜索樹有多少種?
解題報告
完全模仿 Leetcode 95
來實現的。
實現代碼
class Solution {
public:
int helper(int start,int end){
int ret=0;
if(start > end)
return 1;
for(int i=start;i<=end;i++){
int left = helper(start,i-1);
int right = helper(i+1,end);
ret+=left*right;
}
return ret;
}
int numTrees(int n) {
int ret=0;
if(n == 0)
return ret;
return helper(1,n);
}
};
Leetcode 95. 不同的二叉搜索樹 II
問題描述
給定一個整數 n,生成所有由 爲節點所組成的二叉搜索樹。
解題報告
求 1……n
的所有的二叉搜索樹,有以下可能:
- 將
1
作爲根節點,[]
作爲左子樹,[2, ……,n]
組成的所有可能的二叉搜索樹作爲右子樹; - 將
2
作爲根節點,[1]
作爲左子樹,[3, ……,n]
組成的所有可能的二叉搜索樹作爲右子樹; - ……
- 將
n
作爲根節點,[1,……n-1]
的所有可能二叉搜索樹作爲左子樹,[]
作爲右子樹。
根據上面的分析,可以使用遞歸實現。
實現時較爲巧妙的一點是:
if(start>end) ret.push_back(nullptr);
這樣,當調用到 helper(1,1)
時,left
爲 [nullptr]
【存在一個元素的】,同理 right
爲 [nullptr]
【存在一個元素】。
所以
for(auto l:left){
for(auto r:right){
TreeNode* root = new TreeNode(i);
root -> left = l;
root -> right = r;
ret.push_back(root);
}
}
經過這一步,會得到以 1
爲根節點,左子樹和左子樹均爲 null
的二叉搜索樹。
實現代碼
class Solution {
public:
vector<TreeNode*> helper(int start,int end){
vector<TreeNode*> ret;
if(start > end)
ret.push_back(nullptr);
for(int i=start;i<=end;i++){
vector<TreeNode*> left = helper(start,i-1);
vector<TreeNode*> right = helper(i+1,end);
for(auto l : left){
for(auto r : right){
TreeNode* root = new TreeNode(i);
root -> left = l;
root -> right = r;
ret.push_back(root);
}
}
}
return ret;
}
vector<TreeNode*> generateTrees(int n) {
vector<TreeNode*> ret;
if(n == 0)
return ret;
ret = helper(1,n);
return ret;
}
};
// 作者:black-hole
// 鏈接:https://leetcode-cn.com/problems/unique-binary-search-trees-ii/solution/c-30xing-dai-ma-di-gui-by-black-hole/
// 來源:力扣(LeetCode)
// 著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
總結
遞歸法解決二叉樹問題。
參考資料
[1]Leetcode 96. 不同的二叉搜索樹
[2]Leetcode 95. 不同的二叉搜索樹 II
[3]Leetcode 95. 題解區:black-hole
[4] 95*. Unique Binary Search Trees II