unique binary search tree
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
//暴力递归
class Solution {
public:
int numTrees(int n) {
if (0==n)
return 1;
if (1==n)
return 1;
int num = 0;
for(int i=0;i<n;i++)
{
num += numTrees(i)*numTrees(n-1-i);
}
return num;
}
};
//保存结果
class Solution {
public:
int numTrees3(int n)
{
map<int, int>::iterator iter;
if (0==n)
return 1;
if (1==n)
return 1;
iter = mnum.find(n);
if (mnum.end() != iter)
return iter->second;
int num = 0;
for(int i=0;i<n;i++)
{
num += numTrees3(i)*numTrees3(n-1-i);
}
mnum.insert(pair<int,int>(n,num));
return num;
}
map<int, int> mnum;
};
//动态规划
class Solution {
public:
int numTrees(int n) {
if (0==n)
return 1;
if (1==n)
return 1;
map<int, int> mnum;
mnum.insert(pair<int,int>(0,1));
mnum.insert(pair<int,int>(1,1));
for(int i=2;i<=n;i++)
{
int num = 0;
for(int j=0;j<i;j++)
{
num += mnum[j]*mnum[i-1-j];
}
mnum.insert(pair<int,int>(i,num));
// cout<<"mnum "<<i<<" "<<mnum[i]<<endl;
}
return mnum[n];
}
};
//mnum用数组
class Solution {
public:
int numTrees(int n) {
if (0==n)
return 1;
if (1==n)
return 1;
vector<int> mnum(n+1,1);
for(int i=2;i<=n;i++)
{
int num = 0;
for(int j=0;j<i;j++)
{
num += mnum[j]*mnum[i-1-j];
}
mnum[i] = num;
// cout<<"mnum "<<i<<" "<<mnum[i]<<endl;
}
return mnum[n];
};
测试
#include<iostream>
#include<map>
#include<vector>
#include<sys/time.h>
using namespace std;
class Solution {
public:
int numTrees(int n) {
if (0==n)
return 1;
if (1==n)
return 1;
map<int, int> mnum;
mnum.insert(pair<int,int>(0,1));
mnum.insert(pair<int,int>(1,1));
for(int i=2;i<=n;i++)
{
int num = 0;
for(int j=0;j<i;j++)
{
num += mnum[j]*mnum[i-1-j];
}
mnum.insert(pair<int,int>(i,num));
// cout<<"mnum "<<i<<" "<<mnum[i]<<endl;
}
return mnum[n];
}
int numTrees1(int n) {
if (0==n)
return 1;
if (1==n)
return 1;
int num = 0;
for(int i=0;i<n;i++)
{
num += numTrees1(i)*numTrees1(n-1-i);
}
return num;
}
//递归 保存结果相当于动态规划
int numTrees3(int n)
{
map<int, int>::iterator iter;
if (0==n)
return 1;
if (1==n)
return 1;
iter = mnum.find(n);
if (mnum.end() != iter)
return iter->second;
int num = 0;
for(int i=0;i<n;i++)
{
num += numTrees3(i)*numTrees3(n-1-i);
}
mnum.insert(pair<int,int>(n,num));
return num;
}
int numTrees4(int n) {
if (0==n)
return 1;
if (1==n)
return 1;
vector<int> mnum(n+1,1);
for(int i=2;i<=n;i++)
{
int num = 0;
for(int j=0;j<i;j++)
{
num += mnum[j]*mnum[i-1-j];
}
mnum[i] = num;
// cout<<"mnum "<<i<<" "<<mnum[i]<<endl;
}
return mnum[n];
}
map<int, int> mnum;
};
//比较时间
int main()
{
struct timeval start_tv;
struct timeval end_tv;
int n ;
cin>>n;
double time1;
double time2;
double time3;
int a1 = 0;//动态规划比递归但保存结果大的次数;
for (int i=1;i<=n;i++)
{
Solution s;
cout<<"----------"<<i<<"---------"<<endl;
gettimeofday(&start_tv, NULL);
cout<<"n :"<<s.numTrees4(i)<<endl;
gettimeofday(&end_tv, NULL);
time1 = (end_tv.tv_sec - start_tv.tv_sec) + (double)(end_tv.tv_usec - start_tv.tv_usec)/(double)1000000;
cout<<"动态规划时间:"<<time1<<"s"<<endl;
//gettimeofday(&start_tv, NULL);
//cout<<"n :"<<s.numTrees1(i)<<endl;
//gettimeofday(&end_tv, NULL);
//time2 = (end_tv.tv_sec - start_tv.tv_sec) + (double)(end_tv.tv_usec - start_tv.tv_usec)/(double)1000000;
// cout<<"暴力递归:"<<time2<<"s"<<endl;
gettimeofday(&start_tv, NULL);
cout<<"n :"<<s.numTrees3(i)<<endl;
gettimeofday(&end_tv, NULL);
time3 = (end_tv.tv_sec - start_tv.tv_sec) + (double)(end_tv.tv_usec - start_tv.tv_usec)/(double)1000000;
cout<<"递归但保存结果:"<<time3<<"s"<<endl;
//cout<<"暴力递归是动态规划的倍数"<<time2/time1<<endl;
cout<<"动态规划是递归但保存结果的倍数"<<time1/time3<<endl;
if (time1>time3)
a1++;
}
cout<<" 总次数: "<<n<<" 动态规划比递归但保存结果大的次数: "<<a1<<endl;
return 0;
}
//结果不固定,但是整体n很大,动态规划比较好,但是差别不是很大,递归调用时还会花费时间
//总次数: 50 动态规划比递归但保存结果大的次数: 44
//总次数: 500 动态规划比递归但保存结果大的次数: 73
//总次数: 100 动态规划比递归但保存结果大的次数: 72
//总次数: 200 动态规划比递归但保存结果大的次数: 72
//总次数: 300 动态规划比递归但保存结果大的次数: 77
//总次数: 400 动态规划比递归但保存结果大的次数: 74
//总次数: 500 动态规划比递归但保存结果大的次数: 69
//总次数: 600 动态规划比递归但保存结果大的次数: 80
//总次数: 700 动态规划比递归但保存结果大的次数: 80
//总次数: 800 动态规划比递归但保存结果大的次数: 79
//总次数: 900 动态规划比递归但保存结果大的次数: 81