leetcode 823. 带因子的二叉树(dp+双指针+Long类型)
题目表述
给出一个含有不重复整数元素的数组 arr ,每个整数 arr[i] 均大于 1。
用这些整数来构建二叉树,每个整数可以使用任意次数。其中:每个非叶结点的值应等于它的两个子结点的值的乘积。
满足条件的二叉树一共有多少个?答案可能很大,返回 对 1 0 9 + 7 10^9+7 109+7 取余 的结果。
样例
示例 1:
输入: arr = [2, 4]
输出: 3
解释: 可以得到这些二叉树: [2], [4], [4, 2, 2]
示例 2:
输入: arr = [2, 4, 5, 10]
输出: 7
解释: 可以得到这些二叉树: [2], [4], [5], [10], [4, 2, 2], [10, 2, 5], [10, 5, 2].
条件
1 <= arr.length <= 1000
2 <= arr[i] <= 109
arr 中的所有值 互不相同
思路
dp+双指针比较好想
难点有两个:
1、两个子树相同的节点值的时候,不应该是数量相乘再乘2(正常不同值结点计算
s
u
m
=
n
∗
m
∗
2
sum=n*m*2
sum=n∗m∗2),应该是
s
u
m
=
c
n
2
+
n
=
n
2
sum=c^2_n+n=n^2
sum=cn2+n=n2。
2、对于Java中long的使用,如果使用int的范围超过
−
2147483648
至
2147483647
-2147483648 至 2147483647
−2147483648至2147483647int会自动截断然后放到int里。
例子:
System.out.println((18865777)*(36451879));
System.out.println(((long)(18865777)*(36451879)));
会输出
36878647
687693020444983
处理方法就如上述所示,把其中一个数强转为long,这样运算结果会自动强转为long,运算过程也会扩展为long。
注意点
1、Long不支持带e的赋值方法
long x = 10e9+5 //不支持
2、
2
<
=
a
r
r
[
i
]
<
=
1
0
9
2 <= arr[i] <= 10^9
2<=arr[i]<=109所以可以在双指针进入循环前提前判断值的大小问题,超过
1
0
9
10^9
109可以筛掉,此题的数据集应该是最后的大数的量比较多,所以这个点会让速度快一些
下面一个是加了这个筛选的结果。
ac代码
Java:
class Solution {
public int numFactoredBinaryTrees(int[] arr) {
long result=0;
int begin,end;
long mod = 1000000007;
Arrays.sort(arr);
long[] sum = new long[arr.length];
Arrays.fill(sum,1);
for (int i=1;i<arr.length;i++)
{
begin = 0;
end = i-1;
while(begin<=end)
{
if((long)arr[begin]*arr[end]>=mod)
{
end--;
continue;
}
if ((long)arr[begin]*arr[end]==arr[i]) {
sum[i]+=((long)sum[begin]*sum[end]*2);
if (begin==end)
sum[i]-=((long)sum[begin]*sum[end]);
begin++;
sum[i]%=mod;
}
else if ((long)arr[begin]*arr[end]<arr[i])
begin++;
else
end--;
}
}
for (long x:sum)
{
result += x;
result%=mod;
}
return (int)result;
}
}
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/binary-trees-with-factors/description/
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。