Given an array of unique integers, each integer 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 it's children.

How many binary trees can we make?  Return the answer modulo 10 ** 9 + 7.

Example 1:

Input: A = [2, 4]
Output: 3
Explanation: We can make these trees: [2], [4], [4, 2, 2]

Example 2:

Input: A = [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].

Note:

  1. 1 <= A.length <= 1000.
  2. 2 <= A[i] <= 10 ^ 9.
 

这道题给了我们一些不相同的数字,每个都大于1,数字可以重复使用且可以部分使用,问我们可以建立多少棵二叉树使得每个非叶结点的值等于其左右子结点值的乘积。并提示了结果可能会很大,让我们把结果对一个超大数取余。看到这里,刷题老司机们应该瞬间反应过来了吧,应该是用动态规划Dynamic Programming来做,为啥呢,不可能去递归遍历所有的情况阿,这么大的数,机子都要爆了。好吧,既然选定了DP,两个难点,定义dp表达式跟推导状态转移方程。怎么简单怎么来呗,我们用一个一维dp数组,其中dp[i]表示值为i的结点做根结点时,能够形成的符合题意的二叉树的个数。这样我们将数组A中每个结点的dp值都累加起来就是最终的结果了。好了,有了定义式,接下来就是最大的难点了,推导状态转移方程。题目中的要求是根结点的值必须是左右子结点值的乘积,那么根结点的dp值一定是跟左右子结点的dp值有关的,是要加上左右子结点的dp值的乘积的,为啥是乘呢,比如有两个球,一个有2种颜色,另一个有3种颜色,问两个球放一起总共能有多少种不同的颜色组合,当然是相乘啦。每个结点的dp值初始化为1,因为就算是当个光杆司令的叶结点,也是符合题意的,所以至少是1。然后就要找其左右两个子结点了,怎么找,有点像 Two Sum 的感觉,先确定一个,然后在HashMap中快速定位另一个,想到了这一层的话,我们的dp定义式就需要做个小修改,之前说的是用一个一维dp数组,现在看来就不太合适了,因为我们需要快速查找某个值,所以这里我们用一个HashMap来定义dp。好,继续,既然要先确定一个结点,由于都是大于1的正数,那么这个结点肯定要比根结点值小,为了遍历方便,我们想把小的放前面,那么我们就需要给数组A排个序,这样就可以遍历之前较小的数字了,那么如何快速定位另一个子结点呢,我们只要用根结点值对遍历值取余,若为0,说明可以整除,然后再在HashMap中查找这个商是否存在,在的话,说明存在这样的两个结点,其结点值之积等于结点A[i],然后我们将这两个结点值之积加到dp[A[i]]中即可,注意还要对超大数取余,防止溢出。最后当所有结点的dp值都更新完成了,将其和算出来返回即可,参见代码如下:

class Solution {
public:
int numFactoredBinaryTrees(vector<int>& A) {
long res = , M = 1e9 + ;
unordered_map<int, long> dp;
sort(A.begin(), A.end());
for (int i = ; i < A.size(); ++i) {
dp[A[i]] = ;
for (int j = ; j < i; ++j) {
if (A[i] % A[j] == && dp.count(A[i] / A[j])) {
dp[A[i]] = (dp[A[i]] + dp[A[j]] * dp[A[i] / A[j]]) % M;
}
}
}
for (auto a : dp) res = (res + a.second) % M;
return res;
}
};

类似题目:

Two Sum

参考资料:

https://leetcode.com/problems/binary-trees-with-factors/

https://leetcode.com/problems/binary-trees-with-factors/discuss/125794/C%2B%2BJavaPython-DP-solution

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Binary Trees With Factors 带因子的二叉树的更多相关文章

  1. Java实现 LeetCode 823 带因子的二叉树(DP)

    823. 带因子的二叉树 给出一个含有不重复整数元素的数组,每个整数均大于 1. 我们用这些整数来构建二叉树,每个整数可以使用任意次数. 其中:每个非叶结点的值应等于它的两个子结点的值的乘积. 满足条 ...

  2. [Swift]LeetCode823. 带因子的二叉树 | Binary Trees With Factors

    Given an array of unique integers, each integer is strictly greater than 1. We make a binary tree us ...

  3. 【LeetCode】823. Binary Trees With Factors 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 动态规划 相似题目 参考资料 日期 题目地址:htt ...

  4. 【leetcode】823. Binary Trees With Factors

    题目如下: Given an array of unique integers, each integer is strictly greater than 1. We make a binary t ...

  5. LeetCode 617. 合并二叉树(Merge Two Binary Trees)

    617. 合并二叉树 617. Merge Two Binary Trees 题目描述 给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠. 你需要将他们合并为一个新 ...

  6. [LeetCode] Merge Two Binary Trees 合并二叉树

    Given two binary trees and imagine that when you put one of them to cover the other, some nodes of t ...

  7. #Leetcode# 951. Flip Equivalent Binary Trees

    https://leetcode.com/problems/flip-equivalent-binary-trees/ For a binary tree T, we can define a fli ...

  8. [LeetCode] 894. All Possible Full Binary Trees 所有可能的满二叉树

    A full binary tree is a binary tree where each node has exactly 0 or 2 children. Return a list of al ...

  9. [LeetCode] 617. Merge Two Binary Trees 合并二叉树

    Given two binary trees and imagine that when you put one of them to cover the other, some nodes of t ...

随机推荐

  1. MessageFormat的用法,java动态替换String字符串中的占位符

    import java.text.MessageFormat; import java.util.GregorianCalendar; import java.util.Locale; public ...

  2. 如何在IntelliJ IDEA中使用.ignore插件忽略不必要提交的文件

    如何在IntelliJ IDEA中使用.ignore插件忽略不必要提交的文件 最近初学Git,而且在使用的IDE是IntelliJ IDEA,发现IDEA在提交项目到本地仓库的时候,会把.idea文件 ...

  3. Spring Security 之API 项目安全验证(基于basic-authentication)

    ===================================Basic Authorization 规范===================================Request ...

  4. 液晶流在齐次 Besov 空间中的正则性准则

    在 [Zhang, Zujin. Regularity criteria for the three dimensional Ericksen–Leslie system in homogeneous ...

  5. H5取经之路——HTML的基本标签

    一.head中的基本标签 1.HTML文档的结构:     a.<head>头部部分,b.<body>主体部分 <!DOCTYPE html> <!-- ↑为 ...

  6. ADO五大对象

     ADO.NET五大对象, 1. Connection:与数据源建立连接. 2. Command:对数据源执行SQL命令并返回结果. 3. DataReader:读取数据源的数据,只允许对将数据源以只 ...

  7. 封装ajax,让调用变得简单优化

    思考一下: 通常我们在使用ajax来发送接口请求时,每一次都会调用ajax固定的元素,比如data.url.method.success.error等.那么我们想一下能不能先把ajax封装起来,在每次 ...

  8. spring事务源码分析结合mybatis源码(二)

    让我们继续上篇,分析下如果有第二个调用进入的过程. 代码部分主要是下面这个: if (isExistingTransaction(transaction)) { return handleExisti ...

  9. dubbo线程模型

    dubbo的provider有2种线程池: IO处理线程池.(直接通过netty等来配置) 服务调用线程池. 如果事件处理的逻辑能迅速完成,并且不会发起新的 IO 请求,比如只是在内存中记个标识,则直 ...

  10. 2019春季训练02: JU Flash Contest Gym - 102035 训练报告与复盘

    这场题极其简单 Solved 19 / 19 A Gym 102035A N integers 略 Solved 10 / 33 B Gym 102035B Mahmoud the Thief 用ma ...