leetcode-动态规划:Unique Binary Search Trees

i#题目介绍
这道题要求可行的二叉查找树的数量

解题思路

参考http://www.tuicool.com/articles/IFZbAr
其实二叉查找树可以任意取根,只要满足中序遍历有序的要求就可以。从处理子问题的角度来看,选取一个结点为根,就把结点切成左右子树,以这个结点为根的可行二叉树数量就是左右子树可行二叉树数量的乘积,所以总的数量是将以所有结点为根的可行结果累加起来。写成表达式如下:
C0=0 and Cn+1=ni=0CiCni for n>0
,这正是卡特兰数 的一种定义方式,是一个典型的动态规划的定义方式(根据其实条件和递推式求解结果)。所以思路也很明确了,维护量res[i]表示含有i个结点的二叉查找树的数量。根据上述递推式依次求出1到n的的结果即可。
时间上每次求解i个结点的二叉查找树数量的需要一个i步的循环,总体要求n次,所以总时间复杂度是O(1+2+…+n)=O(n^2)。空间上需要一个数组来维护,并且需要前i个的所有信息,所以是O(n)。

实现代码

按照以上的解题思路,很容易实现的代码如下

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
using namespace std;
int numTrees(int n)
{
    int* r = (int*)malloc(sizeof(int) * n);
    r[0] = 1;
    int c;
    for(int i = 0; i < n; i++)
    {
        c = 0;
        for(int j = 0; j <= i; j++)
            c += r[j] * r[i - j];
        r[i + 1] = c;
    }
    return c;
}
int main(int argc, char** argv)
{
    int n = atoi(argv[1]);
    int num = numTrees(n);
    printf("the number of tree is %d\n", num);
    return 0;
}

你可能感兴趣的:(LeetCode)