Unique Binary Search Trees II
@(leetcode)[枚举, DFS]
Given an integer 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
思路
这道题是求解所有可行的二叉查找树,从Unique Binary Search Trees中我们已经知道,可行的二叉查找树的数量是相应的卡特兰数,不是多项式时间的数量级,所以我们要求解所有的树,也不可能在多项式时间内求得解。算法上还是用求解NP问题的方法来求解,思路是每次选取一个结点为根,然后递归求解左右子树的所有结果,最后根据左右子树的返回的所有子树,依次选取然后接上(每个左边的子树跟所有右边的子树匹配,而每个右边的子树也要跟所有的左边子树匹配,总共有左右子树数量的乘积种情况),构造好之后作为当前树的结果返回
代码
/**
* Definition for binary tree
* 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) {
vector<TreeNode*> res;
if(n == 0) {
return res;
}
return build_tree(1, n);
}
private:
vector<TreeNode*> build_tree(int start, int end)
{
vector<TreeNode*> trees;
if(start > end)
{
trees.push_back(NULL);
return trees;
}
if(start == end)
{
trees.push_back(new TreeNode(start));
return trees;
}
for(int i = start; i <= end; i++)
{
//产生以i为根结点的左右子树的所有可能。i取值start到end
vector<TreeNode*> leftTree = build_tree(start, i - 1);
vector<TreeNode*> rightTree = build_tree(i + 1, end);
//将左子树的所有可能和右子树的所有可能连接.leftTree[0]表示第一个节点。
for(int j = 0; j < leftTree.size(); j++)
{
for(int k = 0; k < rightTree.size(); k++)
{
TreeNode* root = new TreeNode(i);
root->left = leftTree[j];
root->right = rightTree[k];
trees.push_back(root); //trees保存当前的根结点
}
}
}
return trees;
}
};