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("\n");
158         }
159         printf("Catalan[%d] = %d\n", n, (int)trees.size());
160         printf("\n");
161     }
162     
163     return 0;
164 }
165 #endif

 

 posted on 2014-02-10 03:16  zhuli19901106  阅读(163)  评论(0编辑  收藏  举报