leetcode 823. 带因子的二叉树
给出一个含有不重复整数元素的数组,每个整数均大于 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.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-trees-with-factors
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
1:先把数组从小到大排序。
2:之后用map来记录每个数字出现的位置。
3:再创建数组counts来记录每个数字为根节点,所能组成二叉树的个数。
4:因为数字是从小到大排列的,所以 若 i 位置的为根节点,则其所有子节点必定在 0 - (i - 1)之间。
5:若arr[i] = arr[m] * arr[n];(0<= m <= n < i)。
1)若 m != n ,则arr[i]为根节点的树的数量 count[i] = count[i] + (count[m] * count[n] * 2)。
因为m n 可以互相交换位置,所以需要 * 2。
2)若 m == n ,则arr[i]为根节点的树的数量 count[i] = count[i] + count[m] * count[n] 。
6:counts中的值默认为1。
7:最后对counts中的元素求和,则为所求答案。为了防止溢出,则用long型来定义变量,组后对1000000007取模。
public int numFactoredBinaryTrees(int[] arr) { int length = arr.length; int m = 1000000007; Map<Integer, Integer> map = new HashMap<>(length << 1); long[] counts = new long[length]; Arrays.sort(arr); for (int i = 0; i < length; i++) { map.put(arr[i], i); } Arrays.fill(counts, 1); Integer value; int item; for (int i = 1; i < length; i++) { int key = arr[i]; int pow = (int) Math.pow(key, 0.5); if (pow * pow == key && (value = map.get(pow)) != null) { counts[i] += counts[value] * counts[value]; pow--; } for (int j = 0; (item = arr[j]) <= pow; j++) { if (key % item == 0 && (value = map.get(key / item)) != null) { counts[i] += ((counts[j] * counts[value]) << 1); } } } long count = 0; for (long i : counts) { count += i; } return (int) (count % m); }