数据结构与算法[LeetCode]—找出N个节点的BST的所有形态组合

Unique Binary Search Trees

Given n, how many structurally unique BST's (binary search trees) that store values 1...n?

For example,
Given n = 3, there are a total of 5 unique BST's.

 1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3
分析:

典型的动态规划(DP)问题:

 本树为二叉搜索树,具有自身特点,左子树小于根节点,右子树大于根节点。

 对于n个节点的BST,设f[n]为结构个数。
依次遍历:1,2,3....n作为树根节点时的结构数目,这n中情况的总和就是n个节点的解。
 针对[1,n]中根k为根时,树的形态有:f[k-1]*f[i-k]中情况。其中,f[k-1]表示左子树有k-1个节点,能组成的形态数。f[i-k]标示右子树有i-k个节点能组成的形态树。

class Solution{
public:
    int numTrees(int n){
        vector<int> f(n+1,0);
        int i,j;
        f[0]=1;
        f[1]=1;
        for(i=2;i<=n;i++)
            for(j=1;j<=i;j++)
                f[i]+=f[j-1]*f[i-j];
        return f[n];
    }
};



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

分析:

使用DFS框架。
由于要打印所有组合树的图形,那么需要输出每种情况的每一个节点。使用动态规划,虽然可以节约递归多次重复计算,但是要访问每次计算细节,所以还是要用DFS(深度搜索)算法。DFS框架使用到了递归,所以不用DP的双重循环,不用先计算一遍0~n-1的各种情况,而是在递归中计算了。

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 generate(1,n);
    }
private:
    vector<TreeNode *> generate(int start,int end){
        vector<TreeNode *>subTrees;
        if(start>end){
            subTrees.push_back(NULL);
            return subTrees;
        }
        int i,j,k;
        for(i=start;i<=end;i++){
            vector<TreeNode *> leftSubs=generate(start,i-1);
            vector<TreeNode *> rightSubs=generate(i+1,end);
            for(j=0;j<leftSubs.size();++j)
                for(k=0;k<rightSubs.size();++k){
                    TreeNode *node=new TreeNode(i);
                    node->left=leftSubs[j];
                    node->right=rightSubs[k];
                    subTrees.push_back(node);
                }
        }
        return subTrees;
    }
};


参考:https://github.com/soulmachine/leetcode

向soulmachine学习!


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值