Unique Binary Search Trees II

来源:互联网 发布:淘宝给的修改评价链接 编辑:程序博客网 时间:2024/06/05 02:13

题目: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

思路:动态规划

本题目思路是动态规划。

 本质上来讲我任选一个节点做根节点,那么我之前的节点都是保存的,我可以直接查表,而之后的dp[i-j]的呢,实际上,只需要把所有后面那部分+j即可。

比如说i=2,j=1,2,假设从1开始  k: 0 – 0  , w: 0 – 0   ,左右各插入一个节点.然后j=2,此时dp[i]又push了2进去。k: 0 – 0  , w: 0 – 0,左边插入一个节点。

也就是说i=2的时候,dp[2]里面保存了前面节点为1 和 为2的树。

假如i=1,dp[1]=1;

想一想:dp[2]  有1,2 其中dp[2][0]节点是1,左指向空,右指向2,dp[2][1]节点是2,左指向1,右指向空。

假如i=3,此时存入数字,dp[3]存入1  2   3。对于dp[3][0]来说,存入两个1,一个2,两个3

j=1:k: 0 – 0  , w: 0 – 1;两个1,左边不能放,dp[2]中存在1,2,右边添加节点1+1,和节点2+1.

j=2:k: 0 – 0  , w: 0 – 0;一个2

j=3:k: 0 – 1  ,  w: 0 – 0;两个3.。。。。。以此类推

 每一个dp[i]里面存放了许多的j,而这些j一共有(i-1)*(i-j)个,而这些dp[i]都是指向左右节点。

代码

/** * Definition for a binary tree node. * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution1 {public:    vector<TreeNode*> generateTrees(int n) {        vector<vector<TreeNode *> >dp(n+1);        if(n<1){            dp[0].push_back(NULL);            return dp[0];        }                dp[0].push_back(NULL);dp[1].push_back(new TreeNode(1));//数字1没有其他节点                for(int i=2;i<=n;i++){            for(int j=1;j<=i;j++){//单独空的节点不考虑了,所以从1开始                for(int k=0;k<dp[j-1].size();k++){                    for(int w=0;w<dp[i-j].size();w++){                        //dp[i]  push 的次数就是k*w的结果,所以每次都是push i一次                        //然后他的back的left指向dp[j]的                        dp[i].push_back(new TreeNode(j));                        dp[i].back()->left=dp[j-1][k];                        traverse_add_copy(dp[i-j][w],dp[i].back()->right,j);                    }                }            }        }        return dp[n];    }      void traverse_add_copy(TreeNode *&root,TreeNode *&dst,int val){        if(root==NULL){            return;        }        dst=new TreeNode(root->val+val);        if(root->left){            traverse_add_copy(root->left,dst->left,val);        }        if(root->right){            traverse_add_copy(root->right,dst->right,val);        }    }};class Solution2 {public:    vector<TreeNode*> generateTrees(int n) {        vector<TreeNode *>result;        helper(1,n,result);        return result;    }        void helper(int start,int end,vector<TreeNode *> &result){        if(start>end){            result.push_back(NULL);            return;//左子树必须小于根节点,所以压入NULL        }                for(int i=start;i<=end;i++){            vector<TreeNode *> tmpLeft,tmpRight;            helper(start,i-1,tmpLeft);            helper(i+1,end,tmpRight);            //生成左右子树,从节点start到i-1,还有就是i+1到end            for(int k=0;k<tmpLeft.size();k++){                for(int j=0;j<tmpRight.size();j++){                    TreeNode *root=new TreeNode(i);                    //本质上是中序遍历                    root->left=tmpLeft[k];                    root->right=tmpRight[j];//左边选择比自己小的,右边选择比自己大的                    result.push_back(root);                }            }        }    }};


0 0
原创粉丝点击