BinaryTreeWithFactors [source code]


public class BinaryTreeWithFactors {
static
/******************************************************************************/
class Solution {
    public int numFactoredBinaryTrees(int[] nums) {
        Arrays.sort (nums);
        int N = nums.length;
        long[] counts = new long[N];
        Arrays.fill (counts, 1);
        long sum = 1;
        for (int i = 1; i < N; i++) {
            countProduct (nums, i, 0, i - 1, counts);
            sum += counts[i];
        }
        return (int) (sum % 10000_00007);
    }

    void countProduct (int[] nums, int target, int lo, int hi, long[] counts) {
        while (lo <= hi) {
            if (nums[target] == nums[lo] * nums[hi]) {
                if (lo == hi) {
                    counts[target] += counts[lo] * counts[lo];
                } else {
                    counts[target] += 2 * counts[lo] * counts[hi];
                }
                // can't break here! think about find 18 in [2,3,6,9]
                hi--;
                lo++;
            } else if (nums[target] < nums[lo] * nums[hi]) {
                hi--;
            } else {
                lo++;
            }
        }
    }
}
/******************************************************************************/

    public static void main(String[] args) {
        BinaryTreeWithFactors.Solution tester = new BinaryTreeWithFactors.Solution();
        int[][] inputs = {
            {2, 4}, {3},
            {2, 4, 5, 10}, {7}, 
            {18, 3, 6, 2}, {12},
            {45,42,2,18,23,1170,12,41,40,9,47,24,33,28,10,32,29,17,46,11,759,37,6,26,21,49,31,14,19,8,13,7,27,22,3,36,34,38,39,30,43,15,4,16,35,25,20,44,5,48}, {777},
            {46,144,5040,4488,544,380,4410,34,11,5,3063808,5550,34496,12,540,28,18,13,2,1056,32710656,31,91872,23,26,240,18720,33,49,4,38,37,1457,3,799,557568,32,1400,47,10,20774,1296,9,21,92928,8704,29,2162,22,1883700,49588,1078,36,44,352,546,19,523370496,476,24,6000,42,30,8,16262400,61600,41,24150,1968,7056,7,35,16,87,20,2730,11616,10912,690,150,25,6,14,1689120,43,3128,27,197472,45,15,585,21645,39,40,2205,17,48,136}, {509730797},
        };
        for (int i = 0; i < inputs.length / 2; i++) {
            System.out.println (Printer.separator ());
            int[] nums = inputs[2 * i];
            int ans = inputs[2 * i + 1][0], output = tester.numFactoredBinaryTrees (nums);
            System.out.printf ("%s\n%s\n%s\n", 
                Printer.array (nums), Printer.wrap (output + "", output == ans ? 92 : 91), ans
            );
        }
    }
}

感觉就是找乘法因子的过程, 好像有点recursion的东西在里面;

这题怎么看起来有点像2sum啊? 每一个数字找自己前面数字里面能够乘积等于自己的? 允许重复使用因子;

尝试写一下; 这题肯定要写的稍微有效一点, 不然会卡复杂度;

看起来这题sort一下应该比较合理, 所以如果写类2sum算法, 直接也写sort的那个版本就行了;

典型例子可以用10找5和2来参考; 然后最后再处理2,4这种情况(2能用两次);

写的过程中发现其实是一个DP题目, 而且root involvement很明显: root就是作为product, 或者说是subtree的root;

因为这题允许重复, 所以最后2pointer移动的时候很费脑筋;

卧槽, 漏看一个条件, 虽然一个数字可以复用, 但是题目规定这个数组本身里面没有重复; 那就简单很多了;

最后还是没有做出来啊, 看起来信心满满; 最后还是被一个大case被break掉了; 感觉是逻辑里面有什么漏洞没有考虑到;

好气啊, 最后就超时一分钟做出来了;

想想也难怪, medium题目作为压轴, 不挖点坑都对不起观众;

总结下来, 这题忽略条件其实也耽误了不少时间, 先是忽略了all unique这个条件, 然后最后那个取模操作也忽略了; 关键最后testcase里面居然还真的有测这个取模的: 导致我一些sum变量全部要换成long;

UNFINISHED


uwi:

class Solution {  
    public int numFactoredBinaryTrees(int[] a) {  
        Arrays.sort(a);  
        a = uniq(a);  
        int n = a.length;  
        int mod = 1000000007;  

        long[] dp = new long[n];  
        long ret = 0;  
        for(int i = 0;i < n;i++){  
            int p = i-1;  
            for(int j = 0;j < i;j++){  
                if(a[i] % a[j] == 0){  
                    while(p >= 0 && a[p] > a[i] / a[j])p--;  
                    if(p >= 0 && a[p] == a[i] / a[j]){  
                        dp[i] += dp[j] * dp[p];  
                        dp[i] %= mod;  
                    }  
                }  
            }  
            dp[i]++;  
            dp[i] %= mod;  
            ret += dp[i];  
        }  
        return (int)(ret%mod);  
    }  

    int[] uniq(int[] a)  
    {  
        int n = a.length;  
        int p = 0;  
        for(int i = 0;i < n;i++) {  
            if(i == 0 || a[i] != a[i-1])a[p++] = a[i];  
        }  
        return Arrays.copyOf(a, p);  
    }  
}

他5分钟做完的, 无语了; 果然这题是有一点DP性质在里面的;

没仔细看了, 不过说实话我自己这题的算法是相当ok了已经; 就是写的慢了;


Problem Description

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 <= A.length <= 1000.
  • 2 <= A[i] <= 10 ^ 9.

Difficulty:Medium
Total Accepted:338
Total Submissions:1.5K
Contributor:ngoc_lam

results matching ""

    No results matching ""