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