例子:
感觉无从下手,此题题为二叉树实际是数组,不需要用到树。
对数组进行排序,排序之后得到有序的数组,从而进行遍历:
定义 d p [ i ] dp[i] dp[i] 表示以 a r r [ i ] arr[i] arr[i] 为根节点的树的数量,可以得出:
{ d p [ a r r [ i ] ∗ a r r [ j ] ] = d p [ a r r [ i ] ] ∗ d p [ a r r [ j ] ] , i = = j d p [ a r r [ i ] ∗ a r r [ j ] ] = d p [ a r r [ i ] ] ∗ d p [ a r r [ j ] ] ∗ 2 , i ! = j \begin{cases} dp[arr[i]*arr[j]] = dp[arr[i]]*dp[arr[j]] ,\quad\quad i==j \\ dp[arr[i]*arr[j]] = dp[arr[i]]*dp[arr[j]]*2 ,\quad i!=j \end{cases} {dp[arr[i]∗arr[j]]=dp[arr[i]]∗dp[arr[j]],i==jdp[arr[i]∗arr[j]]=dp[arr[i]]∗dp[arr[j]]∗2,i!=j
对有序数组遍历时,通过定义一头一尾的指针进行遍历即可,因为数字都不重复,也不存在重复问题。
代码如下:
class Solution {
public static final int MOD = (int) 1e9 + 7;
public int numFactoredBinaryTrees(int[] arr) {
Arrays.sort(arr);
long[] dp = new long[arr.length];
Arrays.fill(dp,1);
for (int i = 1; i < arr.length; i++) {
dp[i] =(dp[i]+ Findnum(arr[i], i - 1, arr, dp)) % MOD;
}
long result = 0;
for (long i : dp) {
result = (result + i) % MOD;
}
return (int)result;
}
public long Findnum(int num, int k, int[] arr, long[] dp) {
long result = 0;
boolean[] used = new boolean[arr.length];
int i = 0, j = k;
while (j>=i){
if ((long)arr[i] * arr[j] == num && !used[i] && !used[j]) {
used[i] = true;
used[j] = true;
if (i == j) result = (result + dp[i] * dp[j]) % MOD;
else result = (result + dp[i] * dp[j] * 2) % MOD;
i++;
j--;
}else {
if((long)arr[i]*arr[j]<num) i++;
if((long)arr[i]*arr[j]>num) j--;
}
}
return result;
}
}
p s : ps: ps: 注意转化为 l o n g long long 类型进行计算