96. Unique Binary Search Trees
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
 
             Important observation for solving the problem: 
            
        - If we keep K as our root, then, all numbers lower than K will come in left subtree and all numbers greater than 1 will come in right subtree.
 - Also, if we have X ways of forming left subtree and Y ways of forming right subtree, then, total number of trees rooted at K can be calculated as : ways(K) = ways(X) * ways(Y).
 - The base case here is, if we have less than 1 nodes left, then we have only one way of forming such subtree.
 
             Solving using recursion (TLE): 
            
        - We have nodes from range [1, n]. We will make it as [0, n - 1] for our convenience.
 - Now suppose we take node 5 as our current root, then, the left subtree will contain nodes [0, 4] and right subtree will contain nodes [6, n - 1].
 - We will solve this recursively, and when we reach our base case, we will return 1 as our answer.
 
            Code using recursion:
            
                class Solution {
                    public int numTrees(int n) {
                        return recur(0, n - 1);
                    }
                    
                    int recur(int l, int r) {
                        // our base case
                        if(l >= r) return 1;
                        int ways = 0;
                        // choosing i as the root node of current subtree
                        for(int i = l; i <= r; i++) {
                            ways = ways + recur(l, i - 1) * recur(i + 1, r);
                        }
                        return ways;
                    }
                }
             
        
        
             Caching the subproblems (TLE to Accepted): 
            
        - Now the above code gives TLE.
 - This is because we are computing subproblems again and again.
 - So we will just cache the results in an array or map, as we want to do.
 
            Code using DP:
            
                class Solution {
                    // array to store results of subproblems
                    Integer[][] dp;
                    public int numTrees(int n) {
                        dp = new Integer[n][n];
                        return recur(0, n - 1);
                    }
                    
                    int recur(int l, int r) {
                        if(l >= r) return 1;
                        
                        // checking if we have already solved this subproblem
                        // if yes, we will return it's answer
                        if(dp[l][r] != null)
                            return dp[l][r];
                        int ways = 0;
                        for(int i = l; i <= r; i++) {
                            ways = ways + recur(l, i - 1) * recur(i + 1, r);
                        }
                        
                        // storing the result of the current subproblem
                        // so that it can be used later on
                        dp[l][r] = ways;
                        
                        return ways;
                    }
                }
             
        
    
Comments
Post a Comment
If you have any queries or need solution for any problem, please let me know.