给出一个含有不重复整数元素的数组,每个整数均大于 1。
我们用这些整数来构建二叉树,每个整数可以使用任意次数。
其中:每个非叶结点的值应等于它的两个子结点的值的乘积。
满足条件的二叉树一共有多少个?返回的结果应模除 10 ** 9 + 7。
示例 1:
输入:A = [2, 4]
输出: 3 解释: 我们可以得到这些二叉树:[2], [4], [4, 2, 2]
示例 2:
输入:A = [2, 4, 5, 10]
输出:7
解释: 我们可以得到这些二叉树:[2], [4], [5], [10], [4, 2, 2], [10, 2, 5], [10, 5, 2]
.
提示:
1 <= A.length <= 1000.
2 <= A[i] <= 10 ^ 9
.
解题思路:
动态规划。假设dp[i]为以数字i为根结点的所有树的总量。
- 当i=a*b,a,b都出现在数组中时,dp[i]+=2*dp[a]*dp[b]。因为子树可以交换位置
- 当i=a*a时,a出现在数组中时,dp[i]+=dp[a]*dp[b]。
- 其余条件dp[i]=1,因此可以将dp的所有元素初始化为1。
- 最终的返回结果是dp中所有元素的和。
注意事项:
- 注意数的范围,每个数最大值10^9,最多1000个,因此用一个long 型数据就够了。
class Solution { public: int numFactoredBinaryTrees(vector<int>& A) { sort(A.begin(), A.end()); unordered_map<int, long> dp; dp[A[0]] = 1; int i, j, size = A.size(); for (i = 1; i <= size; i++) { dp[A[i - 1]] = 1; } long sum = 1; for (i = 2; i <= size; i++) { int val = sqrt(A[i - 1]); for (j = 0; j<i-1&&A[j] <= val; j++) { if (A[i - 1] / A[j]* A[j] ==A[i-1] && (dp[A[j]] && dp[A[i - 1] / A[j]])) { if (A[j] == A[i - 1] / A[j]) { dp[A[i - 1]] += dp[A[j]] * dp[A[i - 1] / A[j]]; } else { dp[A[i - 1]] += 2 * dp[A[j]] * dp[A[i - 1] / A[j]]; } } } sum += dp[A[i - 1]]; } return sum % (1000000007); } }; |