Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to count number of unique binary search tree can be formed with 0 to n values in Python
In this article, we will discuss a problem that involves counting the number of unique binary search tree (BSTs) that can be formed with a given number of nodes. We will explain the problem, test cases, its solution, and provide a Python implementation.
Problem Statement
Given an integer n, we need to find how many structurally unique BSTs can be formed using values from 1 to n. This is known as the Catalan number problem in computer science.
Example 1
<b>Input:</b> n = 3 <b>Output:</b> 5
Explanation: With 3 nodes (values 1, 2, 3), we can form 5 different BST structures ?
Example 2
<b>Input:</b> n = 1 <b>Output:</b> 1 <b>Explanation:</b> With 1 node, only one BST structure is possible.
Understanding the Solution
For any BST with n nodes, we can choose any node i (1 ? i ? n) as the root. This creates:
- Left subtree with (i-1) nodes containing values {1, 2, ..., i-1}
- Right subtree with (n-i) nodes containing values {i+1, i+2, ..., n}
The total number of unique BSTs with root i equals the product of unique BSTs possible in left and right subtrees. We sum this for all possible root choices.
Dynamic Programming Approach
Let dp[i] represent the number of unique BSTs with i nodes. The recurrence relation is ?
dp[i] = ?(dp[j-1] × dp[i-j]) for j from 1 to i
Python Implementation
def num_trees(n):
"""
Count number of unique BSTs with n nodes using dynamic programming
"""
if n <= 1:
return 1
# dp[i] stores number of unique BSTs with i nodes
dp = [0] * (n + 1)
dp[0] = dp[1] = 1 # Base cases
# Fill dp array for 2 to n nodes
for i in range(2, n + 1):
for root in range(1, i + 1):
left_trees = dp[root - 1] # Left subtree possibilities
right_trees = dp[i - root] # Right subtree possibilities
dp[i] += left_trees * right_trees
return dp[n]
# Test the function
test_cases = [1, 2, 3, 4, 5]
for n in test_cases:
result = num_trees(n)
print(f"n = {n}: {result} unique BSTs")
n = 1: 1 unique BSTs n = 2: 2 unique BSTs n = 3: 5 unique BSTs n = 4: 14 unique BSTs n = 5: 42 unique BSTs
Step-by-Step Example (n=3)
For n = 3, we consider each possible root: <b>Root = 1:</b> Left subtree: 0 nodes ? dp[0] = 1 Right subtree: 2 nodes ? dp[2] = 2 BSTs with root 1: 1 × 2 = 2 <b>Root = 2:</b> Left subtree: 1 node ? dp[1] = 1 Right subtree: 1 node ? dp[1] = 1 BSTs with root 2: 1 × 1 = 1 <b>Root = 3:</b> Left subtree: 2 nodes ? dp[2] = 2 Right subtree: 0 nodes ? dp[0] = 1 BSTs with root 3: 2 × 1 = 2 Total: 2 + 1 + 2 = 5 unique BSTs
Complexity Analysis
| Aspect | Complexity | Explanation |
|---|---|---|
| Time | O(n²) | Two nested loops: outer for nodes, inner for root choices |
| Space | O(n) | DP array to store results for each node count |
Conclusion
This problem demonstrates the power of dynamic programming in solving tree-related combinatorial problems. The solution efficiently computes Catalan numbers, which appear frequently in computer science and mathematics.
