welcome to my blog
LeetCode Top 100 Liked Questions 96. Unique Binary Search Trees (Java版; Medium)
题目描述
Given n, how many structurally unique BST's (binary search trees) that store values 1 ...n?
Example:
Input: 3
Output: 5
Explanation:
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) {
/*
首先得知道, 由1,2,3构成的搜索二叉树不是固定的, 并且任何一个数都可以作为树的根, 看题目中的例子
设G(n)表示由1,2,3,...,n这n个数构成的搜索二叉树(BST)的个数
设F(i)表示在1,2,3,...,n这n个数中以i为根节点构成的搜索二叉树的个数, F(i) = G(i-1)*G(n-i)
那么根据上面两个设, 可以有
G(n) = F(1) + F(2) + F(3) +...+ F(n)
带入F(i) = G(i-1)*G(n-i)可得
G(n) = G(0)*G(n-1) + G(1)G(n-2) + G(2)*G(n-3) +...+ G(n-1)*G(0)
*/
int[] dp = new int[n+1];
dp[0]=1;
for(int i=1; i<=n; i++){
for(int j=0; j<i; j++){
dp[i] += dp[j]*dp[i-1-j];
}
}
return dp[n];
}
}
第一次做; 核心设G(n)和F(i), 找出F(i)和G(n)的关系, 找出G(n)和F(i)的关系; 首先得知道, 由1,2,3构成的搜索二叉树不是固定的, 并且任何一个数都可以作为树的根, 看题目中的例子
时间复杂度: 对于外循环中的每个i都要执行i内循环, 所以循环总次数2+3+4+…+n, 时间复杂度为O(N^2)
空间复杂度:O(N)
/*
首先得知道, 由1,2,3构成的搜索二叉树不是固定的, 并且任何一个数都可以作为树的根, 看题目中的例子
设G(n)表示由1,2,3,...,n这n个数构成的搜索二叉树(BST)的个数
设F(i)表示在1,2,3,...,n这n个数中以i为根节点构成的搜索二叉树的个数, F(i) = G(i-1)*G(n-i)
那么根据上面两个设, 可以有
G(n) = F(1) + F(2) + F(3) +...+ F(n)
带入F(i) = G(i-1)*G(n-i)可得
G(n) = G(0)*G(n-1) + G(1)G(n-2) + G(2)*G(n-3) +...+ G(n-1)*G(0)
写几个看看规律
G(0)=1
G(1)=1
G(2)=G(0)*G(1) + G(1)*G(0) = 2
G(3)=G(0)*G(2) + G(1)*G(1) + G(2)*G(0) = 5
*/
class Solution {
public int numTrees(int n) {
if(n<0)
return 0;
if(n<=1)
return 1;
int[] arr = new int[n+1];
arr[0]=1;
arr[1]=1;
int res=0;
for(int i=2; i<=n; i++){
for(int j=0; j<=i-1; j++){
arr[i] += arr[j]*arr[i-1-j];
}
}
return arr[n];
}
}
第一次做; G(n)对应卡塔兰数; 注意代码中除法的位置
1,2,...,n这n个数字构成unique的搜索二叉树的个数正好对应着卡塔兰数
G(0)=1
G(i)=2*(2*i-1)/(i+1)*G(i-1)
class Solution {
public int numTrees(int n) {
if(n<0)
return 0;
if(n<2)
return 1;
long res = 1;
//循环的起始和终止条件
for(int i=2; i<=n; i++){
//细节: 把除法放到最后, 这个地方很麻烦, 因为默认的除法是舍去小数, 把除法往前挪的话算出来的结果就不对了, 这个方法就当是了解一下
res = res * 2 * (2 * i - 1)/(i + 1);
}
return (int)res;
}
}