【Leetcode】823. Binary Trees With Factors

题目地址:

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

给定一个长 n n n的数字各不相同的数组 A A A,并且 ∀ i , A [ i ] > 1 \forall i,A[i]>1 i,A[i]>1。要求以这些数字构成若干非空二叉树,每个非叶子的节点的值应当是其左右孩子的值的乘积(规定非叶子节点必须有两个孩子),问能构成多少个二叉树。每个值可以用无限次。答案模 1 0 9 + 7 10^9+7 109+7返回。

先将 A A A从小到大排序,设 f [ i ] f[i] f[i]是以 A [ i ] A[i] A[i]为树根的情况下能构成多少个不同的二叉树,那么其所有后代的值必然都是 A [ i ] A[i] A[i]之前的值,从而可以枚举其左孩子的值,如果左孩子是 x x x,则右孩子是 A [ i ] / x A[i]/x A[i]/x,如果右孩子的值在 A A A中存在,则这种方案存在,方案数即为以 x x x A [ i ] / x A[i]/x A[i]/x为树根的二叉树方案数的乘积。最后求一下总和即可。代码如下:

class Solution {
 public:
  int numFactoredBinaryTrees(vector<int>& a) {
    const int MOD = 1e9 + 7;
    sort(a.begin(), a.end());
    int n = a.size();
    unordered_map<int, int> mp;
    for (int i = 0; i < n; i++) mp[a[i]] = i;
    long f[n];
    memset(f, 0, sizeof f);
    int res = 0;
    for (int i = 0; i < a.size(); i++) {
      f[i] = 1;
      for (int j = 0; j < i; j++)
        if (a[i] % a[j] == 0) {
          int k = a[i] / a[j];
          if (mp.count(k)) f[i] = (f[i] + f[j] * f[mp[k]]) % MOD;
        }
      res = (res + f[i]) % MOD;
    }

    return res;
  }
};

时间复杂度 O ( n 2 ) O(n^2) O(n2),空间 O ( n ) O(n) O(n)

你可能感兴趣的:(LC,贪心,动态规划与记忆化搜索,leetcode,算法,c++)