LeetCode(95)Unique Binary Search Trees II

题目如下:
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.



分析如下:

上一道题目是相关问题,显然也适合用递归来解决。

当前的递归中,假设root为i。那么显然左子树是由[1,i-1]构成的所有可能的组合,显然右子树是由[i+1,n]构成的所有可能的组合(可以统一记录为,用[start, end]去构建树)。在有了左子树,root,右子树的情况下,根据乘法原理很容易计算得出在当前情况下的所有的树。记录root到一个vector中就可以完整地记录所有结果。返回结果即可。

那么,怎么计算左子树或者右子树的所有可能,这是个和上面类似的问题。

临界条件是,
当[start,end]中star==end时,说明只有一个节点。于是返回这个节点。
当[start,end]中star<end时,返回NULL。


我的代码:
//112ms
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:

    vector<TreeNode*> generateTrees(int n) {
        return generateTrees1(1,n);
    }
    
    vector<TreeNode*> generateTrees1(int start, int end){
        if(start>end){
            vector<TreeNode*> res_vec;
            res_vec.push_back(NULL);
            return res_vec;
        }
        else if(start==end){
            vector<TreeNode*> res_vec;
            TreeNode* res_node=new TreeNode(start);
            res_vec.push_back(res_node);
            return res_vec;
        }
        
        vector<TreeNode*> res_vec;
        for(int i=start;i<=end;i++){
            vector<TreeNode*> l_vec=generateTrees1(start, i-1);
            vector<TreeNode*> r_vec=generateTrees1(i+1,end);
            for(int k=0;k<l_vec.size();k++){
                for(int j=0;j<r_vec.size();j++){
                    TreeNode* root=new TreeNode(i);
                    root->left=l_vec[k];
                    root->right=r_vec[j];
                    res_vec.push_back(root);
                }
            }
        }
        return res_vec;
    }

};


update: 2014-12-19

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
//34ms
class Solution {
public:
    vector<TreeNode*>  generateTreesHelper(int start, int end ) {
        if (start > end) return vector<TreeNode*> {NULL};
        vector<TreeNode*> final;
        for (int i = start; i <= end; ++i) {
            vector<TreeNode*> left = generateTreesHelper(start, i - 1);
            vector<TreeNode*> right = generateTreesHelper(i + 1, end);
            for (int j = 0; j < left.size(); ++j) {
                for (int k = 0; k < right.size(); ++k) {
                    TreeNode* root = new TreeNode(i);
                    root->left = left[j];
                    root->right = right[k];
                    final.push_back(root);
                }
            }
        }
        return final;
    }
        
    vector<TreeNode *> generateTrees(int n) {
        return generateTreesHelper(1, n);
    }
};


update: 

2015-03-23

其实没有上面那个版本写得简单了,上面的版本分了2个情况,下面的版本分了3个情况,虽然都是正确的。

不过,下面的版本用了一下vec.assgin(),以前很少用到这个函数。

// 25ms
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
    
private:
    vector<TreeNode *> generateTrees_(int start, int end) { 
        vector<TreeNode*> vec;
        if (start > end) {
            vec.assign(1, NULL); //Assigns new contents by replacing its current contents.
        } else if (start == end) {
            TreeNode* treenode = new TreeNode(start);
            vec.assign(1, treenode);
        } else {
            for (int i = start; i <= end; ++i) {
                vector<TreeNode*> left_vec = generateTrees_(start, i -1);
                vector<TreeNode*> right_vec = generateTrees_(i + 1, end);
                for (int j = 0; j < left_vec.size(); ++j) {
                    for (int k = 0; k < right_vec.size(); ++k) {
                        TreeNode* treenode = new TreeNode(i);
                        treenode->left = left_vec[j];
                        treenode->right = right_vec[k];
                        vec.push_back(treenode);
                    }
                }
            }
        }
        return vec;
    }
    
public:
    vector<TreeNode *> generateTrees(int n) {
        return generateTrees_(1, n);    
    }
};


小结如下:

 (1)递归每次都返回一堆节点,而不是一个节点。当递归的返回结果为多个时,为了方便处理,可以把这些结果打包放入一个vector中。

 (2) 依然是典型的DFS题目。 



阅读更多
文章标签: LeetCode
上一篇LeetCode(94)Unique Binary Search Trees
下一篇LeetCode(105)Construct Binary Tree from Preorder and Inorder Traversal
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭