zoukankan      html  css  js  c++  java
  • 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

    思路:动态规划

    本题目思路是动态规划。

     本质上来讲我任选一个节点做根节点,那么我之前的节点都是保存的,我可以直接查表,而之后的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);
                    }
                }
            }
        }
    };


  • 相关阅读:
    【转】正则基础之——/b 单词边界
    【转】空格变成问号的怪问题
    【转】正则基础之——NFA引擎匹配原理
    【转】 .NET正则基础之——平衡组
    【转】正则基础之——环视
    【转】正则应用之——日期正则表达式
    【转】正则基础之——小数点
    【转】[ ] 字符组(Character Classes)
    【转】正则表达式30分钟入教程
    【转】正则基础之——非捕获组
  • 原文地址:https://www.cnblogs.com/jsrgfjz/p/8519884.html
Copyright © 2011-2022 走看看