Open In App

Largest BST in a Binary Tree

Last Updated : 22 Nov, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a Binary Tree, the task is to return the size of the largest subtree which is also a Binary Search Tree (BST). If the complete Binary Tree is BST, then return the size of the whole tree.

Examples:

Input:

1

Output: 3
Explanation: The below subtree is the maximum size BST:

2


Input:

largest---------bst---------in---------a---------binary---------tree

Output: 3
Explanation: The below subtree is the maximum size BST:

largest---------bst---------in---------a---------binary---------tree---------2

Prerequisite : Validate BST (Minimum and Maximum Value Approach)

[Naive Approach] Using Recursion - O(n^2) Time and O(n) Space

The idea is simple, we traverse through the Binary tree (starting from root). For every node, we check if it is BST. If yes, then we return size of the subtree rooted with current node. Else, we recursively call for left and right subtrees and return the maximum of two calls.

Below is the implementation of the above approach.

C++
// C++ Program to find Size of Largest BST
// in a Binary Tree

#include <bits/stdc++.h>
using namespace std;

class Node {
public:
    int data;
    Node *left;
    Node *right;
    
    Node(int x) {
        data = x;
        left = nullptr;
      	right = nullptr;
    }
};

// Returns true if the given tree is BST, else false
bool isValidBst(Node *root, int minValue, int maxValue) {
    if (!root)
        return true;
    if (root->data >= maxValue || root->data <= minValue)
        return false;
    return isValidBst(root->left, minValue, root->data) && 
           isValidBst(root->right, root->data, maxValue);
}

// Returns size of a tree
int size(Node *root) {
    if (!root)
        return 0;
    return 1 + size(root->left) + size(root->right);
}

// Finds the size of the largest BST
int largestBst(Node *root) {
  
    // If tree is empty
    if (!root)
        return 0;
    
    // If whole tree is BST
    if (isValidBst(root, INT_MIN, INT_MAX)) 
        return size(root);
  
    // If whole tree is not BST
    return max(largestBst(root->left), 
               largestBst(root->right));
}

int main() {
  
	// Constructed binary tree looks like this:
    //         50
    //       /    \
    //     75      45
    //    /
    //  40

    Node *root = new Node(50);
    root->left = new Node(75);
    root->right = new Node(45);
    root->left->left = new Node(40);

    cout << largestBst(root) << endl;
    return 0;
}
C
// C Program to find Size of Largest
// BST in a Binary Tree
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

struct Node {
    int data;
    struct Node *left, *right;
};

// Returns true if the given tree is BST, else false
int isValidBst(struct Node* root, int minValue, int maxValue) {
    if (!root)
        return 1;
    if (root->data >= maxValue || root->data <= minValue)
        return 0;
    return isValidBst(root->left, minValue, root->data) && 
           isValidBst(root->right, root->data, maxValue);
}

// Returns size of a tree
int size(struct Node* root) {
    if (!root)
        return 0;
    return 1 + size(root->left) + size(root->right);
}

// Finds the size of the largest BST
int largestBst(struct Node* root) {
  
    // If tree is empty
    if (!root)
        return 0;
    
    // If whole tree is BST
    if (isValidBst(root, INT_MIN, INT_MAX)) 
        return size(root);
  
    // If whole tree is not BST
    return (largestBst(root->left) > largestBst(root->right)) 
           ? largestBst(root->left) 
           : largestBst(root->right);
}

struct Node* createNode(int value) {
    struct Node* node = 
      (struct Node*)malloc(sizeof(struct Node));
    node->data = value;
    node->left = node->right = NULL;
    return node;
}

int main() {
  
  	// Constructed binary tree looks like this:
    //         50
    //       /    \
    //     75      45
    //    /
    //  40
    struct Node *root = createNode(50);
    root->left = createNode(75);
    root->right = createNode(45);
    root->left->left = createNode(40);

    printf("%d\n", largestBst(root));
    return 0;
}
Java
// Java Program to find Size of Largest 
// BST in a Binary Tree

class Node {
    int data;
    Node left, right;

    Node(int x) {
        data = x;
        left = null;
        right = null;
    }
}

class GfG {

    // Returns true if the given tree is
  	// BST, else false
    static boolean isValidBst(Node root, int minValue, int maxValue) {
        if (root == null) {
            return true;
        }
        if (root.data >= maxValue || root.data <= minValue) {
            return false;
        }
        return isValidBst(root.left, minValue, root.data) &&
               isValidBst(root.right, root.data, maxValue);
    }

    // Returns size of a tree
    static int size(Node root) {
        if (root == null) {
            return 0;
        }
        return 1 + size(root.left) + size(root.right);
    }

    // Finds the size of the largest BST
    static int largestBst(Node root) {
      
        // If tree is empty
        if (root == null) {
            return 0;
        }

        // If whole tree is BST
        if (isValidBst
            (root, Integer.MIN_VALUE, Integer.MAX_VALUE)) {
            return size(root);
        }

        // If whole tree is not BST
        return Math.max(largestBst(root.left), largestBst(root.right));
    }

    public static void main(String[] args) {
      
      	
        // Constructed binary tree looks like this:
        //         50
        //       /    \
        //     75      45
        //    /
        //  40

        Node root = new Node(50);
        root.left = new Node(75);
        root.right = new Node(45);
        root.left.left = new Node(40);
        System.out.println(largestBst(root));
    }
}
Python
# Python Program to find Size of Largest 
# BST in a Binary Tree

class Node:
    def __init__(self, x):
        self.data = x
        self.left = None
        self.right = None

# Returns true if the given tree is BST, else false
def isValidBst(root, minValue, maxValue):
    if not root:
        return True
    if root.data >= maxValue or root.data <= minValue:
        return False
    return (isValidBst(root.left, minValue, root.data) and
            isValidBst(root.right, root.data, maxValue))

# Returns size of a tree
def size(root):
    if not root:
        return 0
    return 1 + size(root.left) + size(root.right)

# Finds the size of the largest BST
def largestBst(root):
    
    # If tree is empty
    if not root:
        return 0
    
    # If whole tree is BST
    if isValidBst(root, float('-inf'), float('inf')):
        return size(root)
    
    # If whole tree is not BST
    return max(largestBst(root.left), largestBst(root.right))


if __name__ == "__main__":
  
  	# Constructed binary tree looks like this:
    #         50
    #       /    \
    #     75      45
    #    /
    #  40
    
    root = Node(50)
    root.left = Node(75)
    root.right = Node(45)
    root.left.left = Node(40)

    print(largestBst(root))
C#
// C# Program to find Size of Largest 
// BST in a Binary Tree

using System;

class Node {
    public int data;
    public Node left, right;

    public Node(int x) {
        data = x;
        left = null;
        right = null;
    }
}

class GfG {

    // Returns true if the given tree is BST, else false
    static bool IsValidBst(Node root, int minValue, int maxValue) {
        if (root == null) {
            return true;
        }
        if (root.data >= maxValue || root.data <= minValue) {
            return false;
        }
        return IsValidBst(root.left, minValue, root.data) &&
               IsValidBst(root.right, root.data, maxValue);
    }

    // Returns size of a tree
    static int Size(Node root) {
        if (root == null) {
            return 0;
        }
        return 1 + Size(root.left) + Size(root.right);
    }

    // Finds the size of the largest BST
    static int LargestBst(Node root) {
      
        // If tree is empty
        if (root == null) {
            return 0;
        }

        // If whole tree is BST
        if (IsValidBst(root, int.MinValue, int.MaxValue)) {
            return Size(root);
        }

        // If whole tree is not BST
        return Math.Max(LargestBst(root.left), LargestBst(root.right));
    }

    static void Main(string[] args) {
      
      	
        // Constructed binary tree looks like this:
        //         50
        //       /    \
        //     75      45
        //    /
        //  40

        Node root = new Node(50);
        root.left = new Node(75);
        root.right = new Node(45);
        root.left.left = new Node(40);
  
        Console.WriteLine(LargestBst(root));
    }
}
JavaScript
// JavaScript Program to find Size of 
// Largest BST in a Binary Tree

class Node {
    constructor(x) {
        this.data = x;
        this.left = null;
        this.right = null;
    }
}

// Returns true if the given tree is BST, else false
function isValidBst(root, minValue, maxValue) {
    if (!root) return true;
    if (root.data >= maxValue || root.data <= minValue)
        return false;
    return isValidBst(root.left, minValue, root.data) && 
           isValidBst(root.right, root.data, maxValue);
}

// Returns size of a tree
function size(root) {
    if (!root) return 0;
    return 1 + size(root.left) + size(root.right);
}

// Finds the size of the largest BST
function largestBst(root) {
  
    // If tree is empty
    if (!root) return 0;
    
    // If whole tree is BST
    if (isValidBst(root, -Infinity, Infinity)) 
        return size(root);
  
    // If whole tree is not BST
    return Math.max(largestBst(root.left), largestBst(root.right));
}

// Constructed binary tree looks like this:
//         50
//       /    \
//     75      45
//    /
//  40
let root = new Node(50);
root.left = new Node(75);
root.right = new Node(45);
root.left.left = new Node(40);

console.log(largestBst(root));

Output
2

[Expected Approach] - Using Binary Search Tree Property - O(n) Time and O(n) Space

The idea is based on method 3 of check if a binary tree is BST article. A Tree is BST if following is true for every node x.

  • The largest value in left subtree (of x) is smaller than value of x.
  • The smallest value in right subtree (of x) is greater than value of x.

We traverse the tree in a bottom-up manner. For every traversed node, we return the maximum and minimum values in the subtree rooted at that node. The idea is to determine whether the subtree rooted at each node is a Binary Search Tree (BST). If any node follows the properties of a BST and has the maximum size, we update the size of the largest BST.

Step-By-Step Implementation :

  • Create a structure to store the minimum value, maximum value, and size of the largest BST for any given subtree.
  • Implement a recursive function that traverse through the binary tree. For each node, first, recursively gather information from its left and right children.
  • For each node, check whether the current subtree is a BST by comparing the node's value with the maximum of the left subtree and the minimum of the right subtree. If the conditions are satisfied, update the size of the largest BST found by combining the sizes of the valid left and right subtrees with the current node.
  • As the recursive calls return, keep track of the largest BST size. Finally, after traversing the entire tree, return the size of the largest BST found.

Below is the implementation of the above approach.

C++
// C++ Program to find Size of Largest BST in a Binary Tree

#include <bits/stdc++.h>
using namespace std;

class Node {
  public:
    int data;
    Node *left;
    Node *right;

    Node(int val) {
        data = val;
        left = nullptr;
        right = nullptr;
    }
};

// Information about the subtree: Minimum value,
// Maximum value, and Size of the largest BST
class BSTInfo {
  public:
    int min;
    int max;
    int mxSz;

    BSTInfo(int mn, int mx, int sz) {
        min = mn;
        max = mx;
        mxSz = sz;
    }
};

// Function to determine the largest BST in the binary tree
BSTInfo largestBSTBT(Node *root) {
    if (!root)
        return BSTInfo(INT_MAX, INT_MIN, 0);

    BSTInfo left = largestBSTBT(root->left);
    BSTInfo right = largestBSTBT(root->right);

    // Check if the current subtree is a BST
    if (left.max < root->data && right.min > root->data) {
        return BSTInfo(min(left.min, root->data), 
                       max(right.max, root->data), 1 + left.mxSz + right.mxSz);
    }

    return BSTInfo(INT_MIN, INT_MAX, max(left.mxSz, right.mxSz));
}

// Function to return the size of the largest BST
int largestBST(Node *root) {
    return largestBSTBT(root).mxSz;
}

int main() {
  
  	// Constructed binary tree looks like this:
    //         60
    //       /    \
    //      65     70
    //     /
    //   50

    Node *root = new Node(60);
    root->left = new Node(65);
    root->right = new Node(70);
    root->left->left = new Node(50);

    cout << largestBST(root) << endl;

    return 0;
}
Java
// Java Program to find Size of Largest BST in a Binary Tree

class Node {
    int data;
    Node left, right;

    Node(int val) {
        data = val;
        left = null;
        right = null;
    }
}

// Information about the subtree: Minimum value,
// Maximum value, and Size of the largest BST
class BSTInfo {
  int min;
  int max;
  int mxSz;

  BSTInfo(int mn, int mx, int sz) {
    min = mn;
    max = mx;
    mxSz = sz;
  }
}

class GfG {

    // Function to determine the largest BST in the binary
    // tree
    static BSTInfo largestBstBt(Node root) {
        if (root == null)
            return new BSTInfo(Integer.MAX_VALUE,
                            Integer.MIN_VALUE, 0);

        BSTInfo left = largestBstBt(root.left);
        BSTInfo right = largestBstBt(root.right);

        // Check if the current subtree is a BST
        if (left.max < root.data && right.min > root.data) {
            return new BSTInfo(Math.min(left.min, root.data),
                            Math.max(right.max, root.data),
                            1 + left.mxSz + right.mxSz);
        }

        return new BSTInfo(Integer.MIN_VALUE,
                        Integer.MAX_VALUE,
                        Math.max(left.mxSz, right.mxSz));
    }

    // Function to return the size of the largest BST
    static int largestBst(Node root) {
        return largestBstBt(root).mxSz;
    }

    public static void main(String[] args) {
      
		// Constructed binary tree looks like this:
        //         60
        //       /    \
        //      65     70
        //     /
        //   50
        Node root = new Node(60);
        root.left = new Node(65);
        root.right = new Node(70);
        root.left.left = new Node(50);

        System.out.println(largestBst(root));
    }
}
Python
import sys

class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

# BSTInfo structure to store subtree information
class BSTInfo:
    def __init__(self, min_val, max_val, max_size):
        self.min = min_val
        self.max = max_val
        self.maxSize = max_size

# Function to determine the largest BST in the binary tree
def largestBSTBT(root):
    if not root:
        return BSTInfo(sys.maxsize, -sys.maxsize - 1, 0)

    left = largestBSTBT(root.left)
    right = largestBSTBT(root.right)

    # Check if the current subtree is a BST
    if left.max < root.data < right.min:
        return BSTInfo(min(left.min, root.data), max(right.max, root.data), 1 + left.maxSize + right.maxSize)

    return BSTInfo(-sys.maxsize - 1, sys.maxsize, max(left.maxSize, right.maxSize))

# Function to return the size of the largest BST
def largestBST(root):
    return largestBSTBT(root).maxSize

if __name__ == "__main__":
  
    # Constructed binary tree looks like this:
    #         60
    #       /    \
    #      65     70
    #     /
    #   50
    root = Node(60)
    root.left = Node(65)
    root.right = Node(70)
    root.left.left = Node(50)

    print(largestBST(root))
C#
// C# Program to find Size of Largest BST
// in a Binary Tree
using System;

class Node {
    public int data;
    public Node left, right;

    public Node(int val) {
        data = val;
        left = null;
        right = null;
    }
}

// Information about the subtree: Minimum value,
// Maximum value, and Size of the largest BST
class BSTInfo {
    public int min;
    public int max;
    public int mxSz;

    public BSTInfo(int mn, int mx, int sz) {
        min = mn;
        max = mx;
        mxSz = sz;
    }
}

class GfG {

    // Function to determine the largest BST in the binary
    // tree
    static BSTInfo LargestBstBt(Node root) {
        if (root == null)
            return new BSTInfo(int.MaxValue, int.MinValue,
                               0);

        BSTInfo left = LargestBstBt(root.left);
        BSTInfo right = LargestBstBt(root.right);

        // Check if the current subtree is a BST
        if (left.max < root.data && right.min > root.data) {
            return new BSTInfo(
                Math.Min(left.min, root.data),
                Math.Max(right.max, root.data),
                1 + left.mxSz + right.mxSz);
        }

        return new BSTInfo(int.MinValue, int.MaxValue,
                           Math.Max(left.mxSz, right.mxSz));
    }

    // Function to return the size of the largest BST
    static int LargestBst(Node root) {
        return LargestBstBt(root).mxSz;
    }

    static void Main(string[] args) {

        // Constructed binary tree looks like this:
        //         60
        //       /    \
        //      65     70
        //     /
        //   50
        Node root = new Node(60);
        root.left = new Node(65);
        root.right = new Node(70);
        root.left.left = new Node(50);

        Console.WriteLine(LargestBst(root));
    }
}
JavaScript
// JavaScript Program to find Size of Largest
// BST in a Binary Tree

class Node {
    constructor(data) {
        this.data = data;
        this.left = null;
        this.right = null;
    }
}

// BSTInfo class to store subtree information
class BSTInfo {
    constructor(min, max, maxSize) {
        this.min = min;
        this.max = max;
        this.maxSize = maxSize;
    }
}

// Function to determine the largest BST
// in the binary tree
function largestBSTBT(root) {
    if (!root)
        return new BSTInfo
        (Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER, 0);

    const left = largestBSTBT(root.left);
    const right = largestBSTBT(root.right);

    // Check if the current subtree is a BST
    if (left.max < root.data && right.min > root.data) {
        return new BSTInfo(Math.min(left.min, root.data), 
       				 	Math.max(right.max, root.data), 
       				 	1 + left.maxSize + right.maxSize);
    }

    return new BSTInfo(Number.MIN_SAFE_INTEGER, 
    				   Number.MAX_SAFE_INTEGER, 
                       Math.max(left.maxSize, right.maxSize));
}

// Function to return the size of the largest BST
function largestBST(root) {
    return largestBSTBT(root).maxSize;
}

// Constructed binary tree looks like this:
//         60
//       /    \
//      65     70
//     /
//   50
const root = new Node(60);
root.left = new Node(65);
root.right = new Node(70);
root.left.left = new Node(50);

console.log(largestBST(root));

Output
2

Related article:


Next Article

Similar Reads