vector<TreeNode *>* generateTreesHelper(int start, int end, vector<vector<void*> > &dp){
        vector<TreeNode*>* res = new vector<TreeNode*>();
        if(start > end || start == 0){
            res->push_back(NULL);
            if(dp[0][0])
                delete res;
            else
                dp[0][0] = res;
            return (vector<TreeNode*>*)dp[0][0];
        }

        if(dp[start][end])
            return (vector<TreeNode*>*)dp[start][end];
        for(int i = start; i <= end; i++){
            vector<TreeNode *> *left =  generateTreesHelper(start, i-1, dp);
            vector<TreeNode *> *right =  generateTreesHelper(i+1, end, dp);
            for(int l = 0; l < left->size(); l++){
                for(int r = 0; r < right->size(); r++){
                    TreeNode* node = new TreeNode(i);
                    node->left = (*left)[l];
                    node->right = (*right)[r];
                    res->push_back(node);
                }
            }
        }
        dp[start][end] = res;
        return res;
    }
 vector<TreeNode*> generateTreesHelper(int left, int right)
 {
     vector<TreeNode*> nodes;
     if(left>right)
     {
         nodes.push_back(NULL);
         return nodes;
     }
     
     for(int k=left; k<=right; k++)
     {
         vector<TreeNode*> leftnodes=generateTreesHelper(left,k-1);
         vector<TreeNode*> rightnodes=generateTreesHelper(k+1,right);
         for(int i=0; i<leftnodes.size();i++)
         {
             for(int j=0; j<rightnodes.size(); j++)
             {
                 TreeNode* node=new TreeNode(k);
                 node->left=leftnodes[i];
                 node->right=rightnodes[j];
                 nodes.push_back(node);
             }
         }
     }
     
     return nodes;
 }
 vector<TreeNode *> generateTreesHelper(int start, int end){
     vector<TreeNode*> res;
     if(start > end || start == 0){
         res.push_back(NULL);
         return res;
     }
     
     for(int i = start; i <= end; i++){
         vector<TreeNode *> left =  generateTreesHelper(start, i-1);
         vector<TreeNode *> right =  generateTreesHelper(i+1, end);
         for(int l = 0; l < left.size(); l++){
             for(int r = 0; r < right.size(); r++){
                 TreeNode* node = new TreeNode(i);
                 node->left = left[l];
                 node->right = right[r];
                 res.push_back(node);
             }
         }
     }
     return res;
 }
 vector<TreeNode *> generateTrees(int n) {
     vector<vector<void*> > dp(n + 1, vector<void*>(n + 1, NULL));
     vector<TreeNode*> res;
     res = *generateTreesHelper(1, n, dp);
     for(int i = 0; i <= n; i++){
         for(int j = 0; j <= n; j++){
             if(dp[i][j])
                 delete (vector<TreeNode*>*)dp[i][j];
         }
     }
     return res;
 }
 /**
  * @paramn n: An integer
  * @return: A list of root
  */
 vector<TreeNode *> generateTrees(int n) {
     // write your code here
     vector<vector<void*> > dp(n+1, vector<void*>(n+1, NULL));
     vector<TreeNode*> rtn;
     rtn = *generateTreesHelper(1, n, dp);
     for(int i = 0; i <= n; i++){
         for(int j = 0; j <= n; j++){
             if(dp[i][j])
                 delete (vector<TreeNode*>*)dp[i][j];
         }
     }
     return rtn;
 }
 /**
  * @paramn n: An integer
  * @return: A list of root
  */
 vector<TreeNode *> generateTrees(int n) {
     // write your code here
     return generateTreesHelper(1, n);
 }
 vector<TreeNode *> generateTrees(int n) {
     // Start typing your C/C++ solution below
     // DO NOT write int main() function
     return generateTreesHelper(1,n);
 }
 vector<TreeNode *> generateTrees(int n) {
     return generateTreesHelper(1, n);
 }