OJ - 96 不重复的排序二叉树个数

1.题目:给一个正数,返回由[1, n] n个数组成的不重复的排序二叉树的个数。

2.思路:使用动态规划来计算:例如我们在算1-4这四个数有多少个不同的组成的时候,1-4四个数都可以使用来作为根节点,则有下面四种情况:

我们假设我们需要的函数为F(x), 则F(0) = F(1) = 1,F(2) = 2, F(3) = 5【可以自行检验】
① 当1为根节点的时候:那么剩下的元素只能全部在右边:那么右子树唯一的个数为当n为三的时候的个数:F(3)
② 当2为根节点的时候:那么1只能在左边,剩下的3和4只能在右边,左边只有一种组成方式,右边有F(2)种组成方式。
③ 当3为根节点的时候,右边只有4,左边有1和2,跟2为根节点的情况一样。
④ 当4为根节点的时候,剩下的元素只能全部在左边,那么有F(3)种组成方式。
所以总的组成方式就是上面4种情况的总和。

从上面可以看到,反复使用了子结构,所以我们可以使用动态规划来做这个题目:

int numTrees(int n) {
        int size = n+1;
        vector<int> target(size, 1);
        for (int i = 2; i < size; ++i) {
            int current = target[i-1] << 1;  //①
            for (int j = 2; j < i; ++j) {
                current += target[j-1] * target[i-j];  //②
            }
            target[i] = current;
        }
        return target[n];
    }

上面需要解释的两点:

① 为什么要乘2?因为我们在算第n个数的时候,1为根和n为根的情况是一样的,这里我把这两种情况提出来了,所以下面的j是从2开始的。
② 这个内层循环是用来叠加从2开始到n-1为根的情况共有多少种不同的情况。
最后再把对数组赋值就可以得到[1, n]这些数组成的不重复的排序二叉树的个数。

猜你喜欢

转载自blog.csdn.net/nia305/article/details/80229113