1. Recursive Divide and Conquer
Intuition
Any value i in [start, end] can be root. All valid left subtrees are generated by [start, i - 1] and valid right subtrees by [i + 1, end]. For each pair (left, right), create a new TreeNode(i, left, right).
Algorithm
- If start > end, return list containing null (representing empty subtree).
- Initialize list allTrees.
- For i from start to end:
- Generate leftSubtrees = buildTrees(start, i - 1).
- Generate rightSubtrees = buildTrees(i + 1, end).
- For each left in leftSubtrees:
- For each right in rightSubtrees:
- Create root = new TreeNode(i, left, right).
- Append root to allTrees.
- Return allTrees.
#include <iostream>#include <vector> struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} TreeNode(int x, TreeNode *l, TreeNode *r) : val(x), left(l), right(r) {}}; class Solution {public: std::vector<TreeNode*> generateTrees(int n) { if (n == 0) return {}; return build(1, n); } private: std::vector<TreeNode*> build(int start, int end) { if (start > end) return {nullptr}; std::vector<TreeNode*> allTrees; for (int i = start; i <= end; ++i) { std::vector<TreeNode*> leftTrees = build(start, i - 1); std::vector<TreeNode*> rightTrees = build(i + 1, end); for (auto* l : leftTrees) { for (auto* r : rightTrees) { allTrees.push_back(new TreeNode(i, l, r)); } } } return allTrees; }}; int main() { Solution sol; auto trees = sol.generateTrees(3); std::cout << "Generated " << trees.size() << " unique BSTs for n=3 (Expected: 5)\n"; return 0;}Time & Space Complexity
- Time complexity:
O(4^n / sqrt(n)) - Space complexity:
O(4^n / sqrt(n))