96. 不同的二叉搜索树(参考博客通过了)
(没有清晰的思路,没写出来,参考答案的思路之后写出来了)
思路:
效率:
程序代码:
参考网上的答案发现这是一道动态规划问题
我们把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为根的情况)
//96. 不同的二叉搜索树
class Solution {
public:
int numTrees(int n) {
if (n == 0) return 0;
if (n == 1) return 1;
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; j++)
dp[i]+= dp[j]*dp[i - 1 - j];
}
return dp[n];
}
};
int main() {
int n;
cin >> n;
Solution bb;
cout<<bb.numTrees(n)<<endl;
return 0;
}
95. 不同的二叉搜索树 II(通过)
思路:递归
效率:
程序代码:
参考了一点点博客,构建左边,构建右边,合并
class Solution {
public:
vector<TreeNode*> generateTrees(int n) {
if (n == 0) return {};//可以使用这样的方式表达
return Haha(1,n);//其实他返回的是最后一种的情况的根节点
}
//采用的遍历方式时前序遍历
vector<TreeNode*> Haha(int start, int end) {
vector<TreeNode*> result;
if (start > end) result.push_back(NULL);
else {
for (int k = start; k <= end; k++) {
vector<TreeNode*> left = Haha(start, k - 1);
vector<TreeNode*> right = Haha(k + 1, end);
for (auto i : left) {
for (auto j : right) {
TreeNode* root = new TreeNode(k);
root->left = i;
root->right = j;
result.push_back(root);
}
}
}
}
return result;
}
};
虽然调试出来了,但是我非常困惑。。。。调试出来纯粹是意外。。。。
我的程序和参考博客中的程序:
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
vector<TreeNode*> generateTrees(int n) {
if (n == 0) return {};//可以使用这样的方式表达
return Haha(1,n);//其实他返回的是最后一种的情况的根节点
}
//采用的遍历方式时前序遍历
vector<TreeNode*> Haha(int start, int end) {
vector<TreeNode*> result;
if (start > end) result.push_back(NULL);
else {
for (int k = start; k <= end; k++) {
vector<TreeNode*> left = Haha(start, k - 1);
vector<TreeNode*> right = Haha(k + 1, end);
for (auto i : left) {
for (auto j : right) {
TreeNode* root = new TreeNode(k);
root->left = i;
root->right = j;
result.push_back(root);
}
}
}
}
return result;
}
};
class Solution {
public:
vector<TreeNode *> generateTrees(int n) {
if (n == 0) return {};
return *generateTreesDFS(1, n);
}
vector<TreeNode*> *generateTreesDFS(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 = generateTreesDFS(start, i - 1);
vector<TreeNode*> *rightSubTree = generateTreesDFS(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;
}
};