Unique Binary Search Trees - Complete Solution Guide
Unique Binary Search Trees is LeetCode problem 96, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
Given an integer n , return the number of structurally unique BST' s (binary search trees) which has exactly n nodes of unique values from 1 to n . Example 1: Input: n = 3 Output: 5 Example 2: Input: n = 1 Output: 1 Constraints: 1 <= n <= 19
Detailed Explanation
The problem asks us to find the number of structurally unique Binary Search Trees (BSTs) that can be formed using 'n' distinct nodes labeled from 1 to 'n'. A BST is a binary tree where for each node, all nodes in its left subtree have values less than the node's value, and all nodes in its right subtree have values greater than the node's value. The 'structurally unique' part means we're counting trees that have different shapes, even if they contain the same values but arranged differently.
Solution Approach
The provided code uses dynamic programming to calculate the number of unique BSTs. It builds a DP table 'dp' where dp[i] stores the number of unique BSTs with 'i' nodes. The algorithm iterates from 1 to 'n', and for each 'i', it considers each node from 1 to 'i' as the root. For each root 'j', it multiplies the number of unique left subtrees (with 'j-1' nodes, represented by dp[j-1]) with the number of unique right subtrees (with 'i-j' nodes, represented by dp[i-j]). Summing up these products for all possible roots 'j' gives the total number of unique BSTs for 'i' nodes.
Step-by-Step Algorithm
- Step 1: Initialize a DP array 'dp' of size (n+1) with all values set to 0. dp[i] will store the number of unique BSTs with i nodes.
- Step 2: Set the base case: dp[0] = 1. An empty tree (0 nodes) is considered one unique BST.
- Step 3: Iterate from i = 1 to n (inclusive). This loop calculates dp[i] for each i.
- Step 4: Inside the outer loop, iterate from j = 0 to i-1 (inclusive). This loop considers each node j+1 as the root of the BST.
- Step 5: For each j, update dp[i] by adding dp[j] * dp[i - 1 - j]. dp[j] represents the number of unique left subtrees with j nodes, and dp[i - 1 - j] represents the number of unique right subtrees with i-1-j nodes. The '-1' accounts for the root node.
- Step 6: After the outer loop completes, dp[n] will contain the number of unique BSTs with n nodes. Return dp[n].
Key Insights
- Insight 1: The problem can be solved using dynamic programming. The number of BSTs for 'n' nodes can be computed by considering each node from 1 to 'n' as the root and combining the number of possible left and right subtrees.
- Insight 2: The number of BSTs with 'i' nodes can be expressed recursively as the sum of (number of left subtrees with 'j' nodes) * (number of right subtrees with 'i-1-j' nodes), where 'j' ranges from 0 to i-1.
- Insight 3: The base case is when n = 0 or n = 1, where there is only 1 possible BST (an empty tree or a single-node tree).
Complexity Analysis
Time Complexity: O(n^2)
Space Complexity: O(n)
Topics
This problem involves: Math, Dynamic Programming, Tree, Binary Search Tree, Binary Tree.
Companies
Asked at: Adobe, Amazon, Apple, Bloomberg, Clari, Microsoft, Samsung, Snap, TikTok, Tower Research Capital, Yahoo, Zoho.