#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;
/*
问题:
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来做。
找规律:距离,以1作为根节点,那么:后续左右孩子结点{2,3}
{1,2,3}可以认为是选中{1}后,构建{2,3}的二叉查找树,但是似乎不能拆分来看。
因为根节点会决定左右孩子的走向。
设dp[i][j]表示从数字i都数字j的二叉查找树的个数
那么dp[1][n]= dp[1][i-1] * dp[i+1][n] 的累加求和, i从1到n
其中dp[i][i] = 1, dp[i][j] = 1 , 当i > j时
也就是把之前的那道题目拆分
输入:
1
3
输出:
1
5
关键:
1 选定某个根节点为i,然后计算结点i的左子树[1...i-1]的个数,计算结点i的右子树[i+1...n]的个数
则以i为根节点的总的二叉查找树个数=左子树个数 * 右子树个数
对i从1到n遍历,然后累加每个根节点的二叉查找树的个数即可。
2但是超时了,需要记忆化搜索,但是需要注意下标不能溢出
//不断从start到end中选取根节点
int totalResult = 0;
for(int i = start ; i <= end ; i++)
{
leftNum = dfs(start , i-1 , dp );//计算得到左子树的个数
rightNum = dfs(i+1 , end, dp);//计算得到右子树的个数
result = leftNum * rightNum;//以结点i为根节点总的二叉查找树个数=左子树个数*右子树个数
if(i-1 >= 0)
{
dp.at(start).at(i-1) = leftNum;//这边可能溢出
}
if(i+1 <= end)
{
dp.at(i+1).at(end) = rightNum;
}
totalResult += result;
}
*/
class Solution {
public:
int dfs(int start , int end , vector< vector<int> >& dp )
{
int result = 0;
//插入一个空结点,某个结点的左孩子或者右孩子为空
if(start > end)
{
result++;
//dp.at(start).at(end) = result;
return result;
}
//当前结点作为单独的结点。某个结点的左孩子或者右孩子不为空,值为start
if(start == end)
{
result++;
//dp.at(start).at(end) = result;
return result;
}
//记忆化搜索,
if(dp.at(start).at(end) != 0)
{
return dp.at(start).at(end);
}
int leftNum;
int rightNum;
//不断从start到end中选取根节点
int totalResult = 0;
for(int i = start ; i <= end ; i++)
{
leftNum = dfs(start , i-1 , dp );//计算得到左子树的个数
rightNum = dfs(i+1 , end, dp);//计算得到右子树的个数
result = leftNum * rightNum;//以结点i为根节点总的二叉查找树个数=左子树个数*右子树个数
if(i-1 >= 0)
{
dp.at(start).at(i-1) = leftNum;//这边可能溢出
}
if(i+1 <= end)
{
dp.at(i+1).at(end) = rightNum;
}
totalResult += result;
}
return totalResult;
}
int numTrees(int n) {
vector< vector<int> > dp(n+1 , vector<int>(n+1 , 0));
int result = dfs(1 , n , dp);
return result;
}
};
void process()
{
int num;
Solution solution;
int result;
while(cin >> num )
{
result = solution.numTrees(num);
cout << result << endl;
}
}
int main(int argc , char* argv[])
{
process();
getchar();
return 0;
}
leecode 解题总结:96. Unique Binary Search Trees
最新推荐文章于 2024-03-26 15:44:36 发布