1. Top-Down Subtree Validation (O(N^2))
Intuition
For each node in the tree: 1. Check if the subtree rooted at curr is a valid BST by verifying that all values in left subtree are < curr.data and all values in right subtree are > curr.data. 2. If it is a valid BST, count its nodes and return that size. 3. If it is not a valid BST, recursively return max(largestBst(curr.left), largestBst(curr.right)). Because testing BST validity takes O(N) at every node, total time is O(N2) on skewed trees.
When to apply: Baseline brute-force explanation to contrast against bottom-up aggregation.
Algorithm
- For every node, run
isBST(node)in O(size) time. If true, count its size; otherwise recurse on children.
#include <iostream>#include <climits>#include <algorithm> struct Node { int data; Node* left; Node* right; Node(int val) : data(val), left(nullptr), right(nullptr) {}}; class Solution { bool isBST(Node* root, long long minVal, long long maxVal) { if (!root) return true; if (root->data <= minVal || root->data >= maxVal) return false; return isBST(root->left, minVal, root->data) && isBST(root->right, root->data, maxVal); } int size(Node* root) { if (!root) return 0; return 1 + size(root->left) + size(root->right); }public: int largestBst(Node* root) { if (!root) return 0; if (isBST(root, LLONG_MIN, LLONG_MAX)) { return size(root); } return std::max(largestBst(root->left), largestBst(root->right)); }}; int main() { Node* root = new Node(50); root->left = new Node(30); root->right = new Node(60); root->left->left = new Node(5); root->left->right = new Node(20); root->right->left = new Node(45); root->right->right = new Node(70); root->right->right->left = new Node(65); root->right->right->right = new Node(80); Solution sol; std::cout << "Largest BST size: " << sol.largestBst(root) << std::endl; return 0;}Time & Space Complexity
- Time complexity:
O(N^2) worst case - Space complexity:
O(H) recursion stack space