Problem
Given an integer N
, determine how many distinct Max Heaps can be made from N
distinct integers (e.g., 1 to N).
A Max Heap is a complete binary tree where every node is greater than all its children. The structure of the heap is always a complete binary tree, and only the arrangement of values changes.
Input:
- Integer
N
(number of distinct elements)
Output:
- Integer: Number of distinct Max Heaps that can be formed from
N
distinct elements. (Return answer modulo1e9+7
if required)
Examples
Example 1
|
|
Example 2
|
|
Example 3
|
|
Example 4
|
|
Constraints
N <= 100
Solution
Method 1: DP + Combinatorics
Intuition
A Max Heap is a special kind of complete binary tree where every parent node is greater than its children, and the tree is as compact as possible (all levels are filled except possibly the last, which is filled from left to right). For any set of N distinct integers, the largest value must always be at the root of the heap. The remaining (N-1) elements must be distributed among the left and right subtrees, which themselves must also be max heaps and must together form a complete binary tree structure.
The key insight is that the structure of the heap (i.e., the number of nodes in the left and right subtrees) is completely determined by N, due to the properties of complete binary trees. Once the root is fixed, the number of ways to form the heap is determined by:
- Choosing which elements go to the left subtree (the rest go to the right subtree).
- Recursively arranging those elements into valid max heaps in the left and right subtrees.
Thus, the total number of max heaps for N elements is:
C(N-1, L) × ways(L) × ways(R)
where L is the number of nodes in the left subtree, R = N-1-L, and ways(k) is the number of max heaps for k elements.
The challenge is to efficiently compute L for any N, and to avoid recomputation by using dynamic programming and precomputed binomial coefficients.
Approach
-
Base Case: If N is 0 or 1, there is only one possible heap (empty or single node).
-
Root Placement: The largest element always goes at the root.
-
Heap Structure: For a given N, the structure of the complete binary tree determines exactly how many nodes go to the left and right subtrees. This is computed by:
- Finding the height
h
of the heap:h = floor(log2(N))
. - The maximum number of nodes at the last level:
m = 2^h
. - The number of nodes actually present at the last level:
p = N - (2^h - 1)
. - If the last level is at least half full (
p >= m/2
), then the left subtree gets all possible nodes:L = 2^h - 1
. - Otherwise, the left subtree gets fewer nodes:
L = 2^h - 1 - (m/2 - p)
.
- Finding the height
-
Combinatorial Choices: There are
C(N-1, L)
ways to choose which (N-1) elements go to the left subtree. -
Recursion: Recursively compute the number of max heaps for the left and right subtrees.
-
Dynamic Programming: Use memoization to cache results for each N to avoid redundant computation.
-
Binomial Coefficient Precomputation: Precompute all required binomial coefficients for efficiency.
-
Modulo Operation: Since the answer can be large, return the result modulo 1e9+7.
Complexity
- ⏰ Time complexity:
O(N^2)
— There are O(N^2) subproblems due to the DP and binomial coefficient table, and each subproblem is computed in O(1) after memoization. - 🧺 Space complexity:
O(N^2)
— O(N^2) for the nCk table, O(N) for the DP array, and O(N) for the log2 array.
Code
|
|
Python
|
|