码迷,mamicode.com
首页 > 其他好文 > 详细

[LeetCode]Unique Binary Search Trees

时间:2017-04-03 11:45:57      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:pair   root   roo   arch   uniq   nbsp   取值   循环   null   

找值为1->n的所有可能的二叉树。

如果是找可能的数量而不需要列出所有可能时,可以用动态规划。

思路如下:

动态规划法:f(n)表示该子树中有n个数字可用来组成树枝
f(0) = 1;空树
f(1) = 1;树根
f(2) = f(0)*f(1) + f(1)*f(0);当左子树有0个数,右子树右1个数的情况和当左子树有1个数,右子树有0个数的情况;
f(3) = f(0)*f(2) + f(1)*f(1) + f(2)*f(0);

...
f(n) = f(0)*f(n-1) + f(1)*f(n-2) + ... + f(n-1)*f(0);

注意事项:

1.外循环从2开始,内循环不能超过外循环的循环变量;

2。每次开始内循环时,将累加的变量清零。

int numTrees2(int n){
    if (n < 2)return 1;
    vector<int> nums;
    nums.push_back(1);
    nums.push_back(1);
    for (int i = 2; i <= n; i++)
    {
        int num = 0;
        for (int j = 0; j < i; j++)
        {
            num += nums[j] * nums[i - j - 1];
        }
        nums.push_back(num);
    }
    return nums[n];
}

如果要列出所有可能的二叉搜索树,可以在上面的思路上进一步。

f(n) = f(0)*f(n-1) + f(1)*f(n-2) + ... + f(n-1)*f(0);

只要求出不同变量下的子树的所有情况,在整合到一起就可以了。

具体思路:

1.外循环遍历树根可能数值k(m->n);

2.分别求左右子树,左子树的可能取值范围(m->k-1),右子树的可能取值范围(k+1->n);

  注意左右子树可能为空,此时后面合并的时候要分开考虑,因为合并的时候是双重循环,外循环可能为空导致内循环的数据没有机会遍历;

3.最后整合,以当前值k为树根,把左右子树加进去。但是若左子树是l种情况,右子树是r种情况,一共是l*r种情况。

4.以上整个过程用递归描述,递归以当前给的范围来做树根。退出条件是范围内仅有一个可能数值,将它做树根直接返回。

注意:

1.n==0的情况单独考虑

2.左右子树可能为空。

 1 vector<TreeNode*> generateTrees(int n){
 2     vector<TreeNode *>trees;
 3     if (!n){//n==0时,空树
 4         trees.push_back(NULL);
 5         return trees;
 6     }
 7     pair<int, int> border(1,n);
 8     generateTreeNum(trees,border);
 9     return trees;
10 }
11 
12 void generateTreeNum(vector<TreeNode *> &trees, pair<int, int>border){
13     if (border.first == border.second){
14         TreeNode *root = new TreeNode(border.first);
15         trees.push_back(root);
16         return;
17     }
18     for (int i = border.first; i <= border.second; i++)
19     {
20         vector<TreeNode *> lchild;
21         if (i != border.first){//递归求左子树
22             pair<int, int> p(border.first,i - 1);
23             generateTreeNum(lchild, p);
24         }
25         vector<TreeNode *> rchild;
26         if (i != border.second){//递归求右子树
27             pair<int, int> p(i + 1, border.second);
28             generateTreeNum(rchild, p);
29         }
30         if (!lchild.size()){//左子树为空,树根必定为border.first
31             vector<TreeNode *>::iterator it = rchild.begin();
32             while (it != rchild.end()){
33                 TreeNode *root = new TreeNode(border.first);
34                 root->right = (*it);
35                 trees.push_back(root);
36                 ++it;
37             }
38         }
39         else if (!rchild.size()){//右子树为空,树根必定为border.second
40             vector<TreeNode *>::iterator it = lchild.begin();
41             while (it != lchild.end()){
42                 TreeNode *root = new TreeNode(border.second);
43                 root->left = (*it);
44                 trees.push_back(root);
45                 ++it;
46             }
47         }
48         else{
49             vector<TreeNode *>::iterator lit = lchild.begin();
50             vector<TreeNode *>::iterator rit = rchild.begin();
51             while (lit != lchild.end()){
52                 TreeNode *root = new TreeNode(i);
53                 root->left = (*lit);
54                 root->right = (*rit);
55                 trees.push_back(root);
56                 ++rit;//内循环递增右子树的情况
57                 if (rit == rchild.end()){
58                     ++lit;//外循环递增左子树的情况
59                     rit = rchild.begin();
60                 }
61             }
62         }
63     }
64 }

 

[LeetCode]Unique Binary Search Trees

标签:pair   root   roo   arch   uniq   nbsp   取值   循环   null   

原文地址:http://www.cnblogs.com/yeqluofwupheng/p/6661393.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!