一、问题描述:
Given n, generate all structurally unique BST's (binary search trees) that store values 1...n.
For example,
Given n = 3, your program should return all 5 unique BST's shown below.
1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3
confused what "{1,#,2,3}"
means? > read more on how binary tree is serialized on OJ.
二、解题思路:
这是一道动态规划的题目,设对于有i个节点时能生成的二叉搜索树的形态全部存储在ans[i]中。
首先分析对于有n个节点的二叉搜索树,如果它以i(1<=i<=n)为根,可以生成左子树的形态全部存储在ans[i-1]中,可以生成的右子树的形态全部存储在ans[n-i]中,只不过对于右子树的每个对应形态,其中的每个节点的val值都要增加i。所以对于以i为根的n个节点的二叉搜索树其所有形态即为每个左子树形态分别匹配每个右子树形态。
最后对于ans[n],它的所有形态即为根节点为i的各个形态的集合。
注意:
对于右子树采用递归的方式创建,而不能简单的将其加i,这样会影响到之前生成的二叉搜索树。
三、代码:beats 90%+ submissions in cpp
class Solution { public: vector<TreeNode*> generateTrees(int n) { vector<vector<TreeNode*>> ans; TreeNode *root = new TreeNode(1); vector<TreeNode*> v; ans.push_back(v); v.push_back(root); ans.push_back(v); for (int i = 2; i <= n; ++i) { vector<TreeNode*> tmp; for (int l = 0; l < ans[i-1].size(); ++l) { // deal with j=1 root = new TreeNode(1); root->right = build(ans[i-1][l], 1); tmp.push_back(root); } for (int j = 2; j < i; ++j) { for (int k = 0; k < ans[j-1].size(); ++k) { for (int l = 0; l < ans[i-j].size(); ++l) { root = new TreeNode(j); root->left = ans[j-1][k]; root->right = build(ans[i-j][l], j); tmp.push_back(root); } } } for (int l = 0; l < ans[i-1].size(); ++l) { // deal with j=i root = new TreeNode(i); root->left = ans[i-1][l]; tmp.push_back(root); } ans.push_back(tmp); } return ans[n]; } private: TreeNode* build(TreeNode* rightRoot, int rootVal) { if (rightRoot == NULL) return NULL; TreeNode *newRoot = new TreeNode(rightRoot->val+rootVal); newRoot->left = build(rightRoot->left, rootVal); newRoot->right = build(rightRoot->right, rootVal); return newRoot; } };