# Unique Binary Search Trees

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

## Analysis

To answer how many unique BSTs, need to know how to build a BST first. The approach could be recursively construct left and right sub-trees (https://www.geeksforgeeks.org/construct-all-possible-bsts-for-keys-1-to-n/\:
1) Initialize list of BSTs as empty.
2) For every number i where i varies from 1 to N, do following
......a) Create a new node with key as 'i', let this node be 'node'
......b) Recursively construct list of all left subtrees.
......c) Recursively construct list of all right subtrees.
3) Iterate for all left subtrees
a) For current leftsubtree, iterate for all right subtrees
'node' to list.
For a sorted sequence: `1 ... n`, construct BST:
1. 1.
select `i` in the sequence
2. 2.
sub sequence `1 ... (i - 1)` on the left
3. 3.
sub sequence `(i+1) ... n` on the right
4. 4.
construct the sub tree from the sub sequence recursively
Dynamic Programming
The two functions (state):
`G(n)`- the number of unique BST for a sequence of length `n`.
`F(i, n)` - the number of unique BST, where the number i is served as the root of BST `(1 ≤ i ≤ n)`.
Where
`G(n) = SUM(F(i, n)) over i = 1, ..., n.`
And
`F (i, n) = G(i - 1) * G(n - i)`
Thus
`G(n) = SUM(G(i - 1) * G(n - i)) over i = 1, ..., n`
Initial State:
`G(0) = 1, G(1) = 1`
`G(n)` is actually the desired function we need in order to solve the problem.

## Solution

DP - O(n^2) time, O(n) space (0ms, 100% AC)
class Solution {
public int numTrees(int n) {
if (n < 2) return 1;
int[] uniqueTrees = new int[n + 1];
uniqueTrees = 1;
uniqueTrees = 1;
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= i; j++) {
uniqueTrees[i] += uniqueTrees[j - 1] * uniqueTrees[i - j];
}
}
return uniqueTrees[n];
}
}
Math - Catalan Number
class Solution {
public int numTrees(int n) {
// Note: we should use long here instead of int, otherwise overflow
long C = 1;
for (int i = 0; i < n; ++i) {
C = C * 2 * (2 * i + 1) / (i + 2);
}
return (int) C;
}
}