zoukankan      html  css  js  c++  java
  • LeetCode

    Unique Binary Search Trees II

    2014.2.10 02:54

    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.

    Solution:

      You know that the total number of binary search trees of n nodes is the nth Catalan number. But this time you have to build them all. It's hard labor, you know, both for the computer and for you.

      My solution is recursive, here is the description:

        1. for the sorted array a[1:n], pick some a[x] as the root. Every node a[i] will be the root node for some times. Thus this recursion has n branch.

        2. the left sub-array a[1:x-1] forms the left subtree, the right sub-array a[x+1:n] forms the right subtree.

        3. the left and right recursions return both result sets containing left subtrees and right subtrees.

        4. picking one from the left, and one from the right, together with the root node, you get a larger tree.

        5. put this larger tree in the result set. That's how a tree is built up.

      I've written a funtion copyTreeRecursive() to do a deep copy of trees, but later I realized that shallow copy of TreeNode pointers works just as fine, and would save a lot of allocated memory. If you're interested, please view the commented code segment below and find out why.

      Total time and space complexities are both O(n!) scale, as the nth Catalan number is C(2*n, n) / (n+ 1).

      The time and space usage of this algorithm is explosive, so it's quite easy to get a "Stackoverflow" from this program. You better expect n to be under 10, if you're waiting to see the result.

    Accepted code:

      1 // 1WA, 1AC, very good~
      2 // #define MY_MAIN
      3 #include <cstdio>
      4 #include <vector>
      5 using namespace std;
      6 /**
      7  * Definition for binary tree
      8  * struct TreeNode {
      9  *     int val;
     10  *     TreeNode *left;
     11  *     TreeNode *right;
     12  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     13  * };
     14  */
     15 
     16 #ifdef MY_MAIN
     17 struct TreeNode {
     18     int val;
     19     TreeNode *left;
     20     TreeNode *right;
     21     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     22 };
     23 #endif
     24 class Solution {
     25 public:
     26     vector<TreeNode *> generateTrees(int n) {
     27         int i;
     28         vector<int> num;
     29         vector<TreeNode *> result;
     30         
     31         result.clear();
     32         if (n == 0) {
     33             // 1WA here, you should return an empty tree when n=0.
     34             result.push_back(NULL);
     35             return result;
     36         }
     37         
     38         for (i = 1; i <= n; ++i) {
     39             num.push_back(i);
     40         }
     41         result = generateTreeRecursive(num);
     42         return result;
     43     }
     44 private:
     45     vector<TreeNode *> generateTreeRecursive(vector<int> num) {
     46         vector<TreeNode *> res;
     47         TreeNode *root_ptr;
     48         
     49         res.clear();
     50         if (num.size() == 0) {
     51             res.push_back(NULL);
     52             return res;
     53         } else if (num.size() == 1) {
     54             root_ptr = new TreeNode(num[0]);
     55             res.push_back(root_ptr);
     56             return res;
     57         }
     58         
     59         vector<int> vleft, vright;
     60         vector<TreeNode *> res_left, res_right;
     61         int count_left, count_right;
     62         int i, j, k;
     63         
     64         for (i = 0; i < (int)num.size(); ++i) {
     65             vleft.clear();
     66             vright.clear();
     67             res_left.clear();
     68             res_right.clear();
     69             // the left subtree
     70             for (j = 0; j < i; ++j) {
     71                 vleft.push_back(num[j]);
     72             }
     73             // the right subtree
     74             for (j = i + 1; j < (int)num.size(); ++j) {
     75                 vright.push_back(num[j]);
     76             }
     77             res_left = generateTreeRecursive(vleft);
     78             res_right = generateTreeRecursive(vright);
     79             count_left = (int)res_left.size();
     80             count_right = (int)res_right.size();
     81             for (j = 0; j < count_left; ++j) {
     82                 for (k = 0; k < count_right; ++k) {
     83                     root_ptr = new TreeNode(num[i]);
     84                     // root_ptr->left = copyTreeRecursive(res_left[j]);
     85                     // root_ptr->right = copyTreeRecursive(res_right[k]);
     86                     root_ptr->left = res_left[j];
     87                     root_ptr->right = res_right[k];
     88                     res.push_back(root_ptr);
     89                 }
     90             }
     91         }
     92         
     93         return res;
     94     }
     95 
     96     TreeNode *copyTreeRecursive(const TreeNode *root)
     97     {
     98         TreeNode *new_root;
     99         
    100         if (root == NULL) {
    101             return NULL;
    102         }
    103         new_root = new TreeNode(root->val);
    104         if (root->left != NULL) {
    105             new_root->left = copyTreeRecursive(root->left);
    106         }
    107         if (root->right != NULL) {
    108             new_root->right = copyTreeRecursive(root->right);
    109         }
    110 
    111         return new_root;
    112     }
    113 };
    114 
    115 #ifdef MY_MAIN
    116 void preorderTraversal(const TreeNode *root, vector<int> &result)
    117 {
    118     if (root == NULL) {
    119         result.push_back(0);
    120     }
    121     result.push_back(root->val);
    122     if (root->left != NULL) {
    123         preorderTraversal(root->left, result);
    124     } else {
    125         result.push_back(0);
    126     }
    127     if (root->right != NULL) {
    128         preorderTraversal(root->right, result);
    129     } else {
    130         result.push_back(0);
    131     }
    132 }
    133 
    134 int main()
    135 {
    136     int n;
    137     Solution solution;
    138     vector<int> traversal_result;
    139     vector<TreeNode *> trees;
    140     int i, j;
    141     
    142     while (scanf("%d", &n) == 1) {
    143         if (n < 0) {
    144             continue;
    145         }
    146         trees = solution.generateTrees(n);
    147         for (i = 0; i < (int)trees.size(); ++i) {
    148             traversal_result.clear();
    149             preorderTraversal(trees[i], traversal_result);
    150             for (j = 0; j < (int)traversal_result.size(); ++j) {
    151                 if (j == 0) {
    152                     printf("%d", traversal_result[j]);
    153                 } else {
    154                     printf(" %d", traversal_result[j]);
    155                 }
    156             }
    157             printf("
    ");
    158         }
    159         printf("Catalan[%d] = %d
    ", n, (int)trees.size());
    160         printf("
    ");
    161     }
    162     
    163     return 0;
    164 }
    165 #endif
  • 相关阅读:
    如何理解python中的if __name__=='main'的作用
    如何在阿里云上部署war包到tomcat服务器
    如何在windows上部署war包到tomcat服务器
    解决:mysql5.7 timestamp默认值0000-00-00 00:00:00 报错
    python3中的unicode_escape
    python中的excel操作
    python的logging模块
    python中的SMTP发送邮件
    python中的字符串
    一道问题引出的python中可变数据类型与不可变数据类型
  • 原文地址:https://www.cnblogs.com/zhuli19901106/p/3542212.html
Copyright © 2011-2022 走看看