Binary Trees With Factors
MediumUpdated: Aug 2, 2025
Practice on:
Problem
Given an array of unique integers, arr, where each integer arr[i] is strictly greater than 1.
We make a binary tree using these integers, and each number may be used for any number of times. Each non-leaf node's value should be equal to the product of the values of its children.
Return the number of binary trees we can make. The answer may be too large so return the answer modulo 10^9 + 7.
Examples
Example 1:
Input: arr = [2,4]
Output: 3
Explanation: We can make these trees: `[2], [4], [4, 2, 2]`
Example 2:
Input: arr = [2,4,5,10]
Output: 7
Explanation: We can make these trees: `[2], [4], [5], [10], [4, 2, 2], [10, 2, 5], [10, 5, 2]`.
Solution
Method 1 - Using DP
Here is the approach:
- Sorting Input: First, sort the array to process smaller values first.
- Dynamic Programming: Use a hashmap (
dp) wheredp[x]represents the number of binary trees with root valuex. Initially, each integer is considered to have one tree where the integer itself is the root node (leaf tree). - Traversal: Iterate through each value in the array and calculate the number of trees it can represent as roots:
- For each integer
x, loop through every possible left childl(whereldividesxevenly). - Calculate the right child (
r) asx / l. - If both
landrexist in the array, multiply the count of trees rooted atlandr, then add this count todp[x].
- For each integer
- Result: Sum all values in
dpmodulo (10^9 + 7).
Code
Java
class Solution:
def numFactoredBinaryTrees(self, arr: List[int]) -> int:
MOD = 10**9 + 7
arr.sort()
dp = {}
ans = 0
for x in arr:
dp[x] = 1 # Initial tree with root x itself
for l in arr:
if l >= x: # Break early as we only need values smaller than x
break
if x % l == 0:
r = x // l
if r in dp:
dp[x] += dp[l] * dp[r]
dp[x] %= MOD
ans = (ans + dp[x]) % MOD
return ans
Python
class Solution {
public int numFactoredBinaryTrees(int[] arr) {
int MOD = 1_000_000_007;
Arrays.sort(arr);
Map<Integer, Long> dp = new HashMap<>();
long ans = 0;
for (int x : arr) {
dp.put(x, 1L); // Initial tree with root value x itself
for (int l : arr) {
if (l >= x) { // Break early for efficiency
break;
}
if (x % l == 0) {
int r = x / l;
if (dp.containsKey(r)) {
dp.put(x, dp.get(x) + dp.get(l) * dp.get(r));
dp.put(x, dp.get(x) % MOD);
}
}
}
ans = (ans + dp.get(x)) % MOD;
}
return (int) ans;
}
}
Complexity
- Time:
O((n^2 + n log n), wherenis the size of the array.O(n log n)for sorting.O(n^2)for nested loops, since for each value we loop through possible left children.
- Space:
O(n)fordphashmap.