#894

All Possible Full Binary Trees

Medium
Dynamic ProgrammingTreeRecursionMemoizationBinary TreeDynamic ProgrammingRecursion
LeetCode ↗

Approaches

Brute ForceOptimal
Complexity Comparison
Brute ForceOptimal Solution
Time
O(n²)
O(n³)
Space
O(1)
O(n)
💡

Intuition

Time O(n³)Space O(n)

The optimal solution uses dynamic programming to store previously computed results for each number of nodes. This avoids redundant calculations and speeds up the process significantly.

⚙️

Algorithm

3 steps
  1. 1Step 1: Create a memoization table to store results for each odd number of nodes.
  2. 2Step 2: For each odd number of nodes, generate trees by combining results from smaller subproblems.
  3. 3Step 3: Use the memoization table to retrieve results instead of recalculating them.
solution.py21 lines
1class TreeNode:
2    def __init__(self, val=0):
3        self.val = val
4        self.left = None
5        self.right = None
6
7def allPossibleFBT(n):
8    if n % 2 == 0:
9        return []
10    memo = {1: [TreeNode(0)]}
11    for i in range(3, n + 1, 2):
12        memo[i] = []
13        for left in range(1, i, 2):
14            right = i - 1 - left
15            for left_tree in memo[left]:
16                for right_tree in memo[right]:
17                    root = TreeNode(0)
18                    root.left = left_tree
19                    root.right = right_tree
20                    memo[i].append(root)
21    return memo[n]

Complexity note: The time complexity is O(n³) due to the nested loops for generating left and right subtrees for each odd number of nodes. The space complexity is O(n) for storing the results in the memoization table.

  • 1Full binary trees can only have an odd number of nodes.
  • 2Dynamic programming helps avoid redundant calculations.

Solutions and explanations are original Tejav content. Problem titles © LeetCode — use the LeetCode button above for the full problem statement.