[LeetCode P96] Unique Binary Search Trees II

来源:互联网 发布:国裕数据 编辑:程序博客网 时间:2024/06/08 10:46

原题:

原题:Given an integer 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

解题思路:
这个题的P97简单版可以用DP解决,可以选择先把P97做了,然后做这题,还是纠结了挺久,主要是在不知道有没有更快的方法的情况下,不敢轻易开码,最后还是选择和P97一样的思路,这里我还是用了DP,用来减少一些花销。
代码如下(思路主要见注释):

// 是一道好题,但这题一直不太敢写,因为我一直觉得会有很简单的方法// 但是事实证明好像大家都没有想到好的解法// 那样的话就用上一题的思路解决它吧,我们还是用到了DP// 不过DP只有在左侧可以复用节点,但是在右侧我们不可以复用结点// 右侧我们要进行深拷贝,深拷贝可以用递归进行// ==》DP的时间复杂度和空间复杂度都是比直接递归做要节约挺多的// 最终的时间复杂度有点太高了,比较难计算class Solution {public:    TreeNode* copyTree(TreeNode* root, int inc){        // 递归地深拷贝这棵树,注意要加上偏移量        if (root == NULL) return NULL;        TreeNode* newRoot = new TreeNode(root->val + inc);        newRoot->left = copyTree(root->left, inc);        newRoot->right = copyTree(root->right, inc);        return newRoot;    }    vector<TreeNode*> generateTrees(int n) {        const int size = n;        vector<vector<TreeNode*>> dp(size+1);        if(n == 0)return dp[0];        dp[0].push_back(NULL);        for (int i = 1; i <= n; ++i)        {            // 自底向上构建dp            for (int j = 1; j <= i; ++j)            {                // 选择一个作为根节点                int leftSize = j - 1;                int rightSize = i - j;                for (int k = 0; k < dp[leftSize].size(); ++k)                {                    // 左侧的dp[leftSize].size()种可能                    for (int l = 0; l < dp[rightSize].size(); ++l)                    {                        // 右侧的dp[rightSize].size()种可能,注意这棵树里的节点全都要加上j                        TreeNode *root = new TreeNode(j);                        root->left = dp[leftSize][k];                        // 左侧树可以不用更改                        root->right = copyTree(dp[rightSize][l], j);                        // 我们可以直接拷贝,由于rightSize+j=i                        // 所以每次i,这颗右边的树都是不同的,每次都要深拷贝                        dp[i].push_back(root);                        // 最后把候选解放进去                    }                }            }        }        return dp[n];    }};
原创粉丝点击