美文网首页算法
823. 带因子的二叉树

823. 带因子的二叉树

作者: 红树_ | 来源:发表于2023-08-30 17:00 被阅读0次

扩展生活的视野,主要靠开阔心胸。 - Hugh Black。

题目

LC每日一题,参考823. 带因子的二叉树,难度分1900。

解题思路

  • 动态规划 + 双指针或哈希表:首先肯定是排序,从小到大计算每一个数作为根节点的所有可能数,而因子叶节点肯定比当前数小,所以可以应用动态规划(也可以使用递归记忆化搜索),转移方程为dp[i] = 1 + dp[left] * dp[right] * (1 +(left<right?1:0))(left和right为所有满足arr[left]*arr[right]=arr[i]的下标)(具体解释和实现请参考以下注释和代码);对于所有可能的因子数,可以使用双指针查找或者使用哈希表判断因子数是否能被arr[i]整除和被整除的数是否在哈希表里面。

动态规划 + 双指针 15ms

class Solution {
    public int numFactoredBinaryTrees(int[] arr) {
        int n = arr.length, MOD = (int)(1e9+7);
        long ans = 0;
        //首先肯定排序 
        Arrays.sort(arr);
        //从值小的开始计算 应用动态规划
        long[] dp = new long[n];
        for(int i = 0; i < n; i++) {
            dp[i] = 1; //本身1
            //使用双指针找所有满足cur的因子叶节点 因为cur>=2所以范围0,i-1
            int cur = arr[i];
            int left = 0, right = i-1;
            while(left <= right) {
                //必须用long接收target否则溢出会计算不准确
                long target = (long)arr[left] * arr[right];
                if(target > cur) right--;//先判断大于是个技巧,有取模数一般很大,加大命中率
                else if(target < cur) left++;
                else {
                    //对于所有满足的因子都有left,right < i 所以可用前面的dp来求
                    dp[i] += dp[left] * dp[right] * (1 +(left<right?1:0));
                    left++;
                    right--;
                }
            }
            ans += dp[i];
        }
        return (int)(ans%MOD);
    }
}

复杂度分析

  • 时间复杂度:O(n^2),双重枚举循环,n为数组长度。
  • 空间复杂度:O(n),动态规划所用空间。

相关文章

网友评论

    本文标题:823. 带因子的二叉树

    本文链接:https://www.haomeiwen.com/subject/jukamdtx.html