[M数学] lc3164. 优质数对的总数 II(因数分解+倍增+推公式+思维+好题)

文章目录

    • [1. 题目来源](#1. 题目来源)
    • [2. 题目解析](#2. 题目解析)

1. 题目来源

链接:3164. 优质数对的总数 II

2. 题目解析

挺不错的一道 因数分解、倍增 的题目,需要一定的思维和推公式的能力才能解决。灵神的题解已经非常清晰易懂了,可以直接去看。

倍增思路:

  • 枚举 num1、nums2 每个数出现的次数。
  • 再枚举 nums2 * k 的倍数,如果在 nums1 中有出现,则基于乘法原理,两个次数相乘累加结果。
  • 倍数累计的上界即为 nums1 中的最大值。

分解因数思路:

  • 考虑,nums1i % (nums2j * k) == 0 则有,(nums1i / k) % nums2j == 0
  • 即,nums1i 首先是 k 的倍数,且 nums1i/k 存在因子 nums2j
  • 那么可以针对 nums1i/k 分解它的各个因子,并记录个数,此时 cnta=b 则等价于有 b 个 numsi/k 存在因子 a
  • 枚举每一个 nums2,答案累加 cntnums2\[j] 即可。

具体的,见灵神题解,很清楚了:


这个东西分析有点难度,见灵神的分析吧...


因数分解代码:

cpp 复制代码
class Solution {
public:
    long long numberOfPairs(vector<int>& nums1, vector<int>& nums2, int k) {
        typedef long long LL;
        unordered_map<int, int> h;
        for (auto x : nums1) {
            if (x % k) continue;
            x /= k;
            for (int i = 1; i <= x / i; i ++ ) {
                if (x % i) continue;
                h[i] ++ ;
                if (i * i < x) h[x / i] ++ ;
            }
        }

        LL res = 0;
        for (int x : nums2) res += h[x];
        return res;
    }
};

倍增代码:

cpp 复制代码
class Solution {
public:
    long long numberOfPairs(vector<int>& nums1, vector<int>& nums2, int k) {
        typedef long long LL;
        unordered_map<int, int> cnt1, cnt2;
        for (auto x : nums1) 
            if (x % k == 0)
                cnt1[x / k] ++ ;
        
        for (auto x : nums2) cnt2[x] ++ ;

        int u = -1;
        for (auto [k, v] : cnt1) u = max(u, k);

        LL res = 0;
        for (auto [x, cnt] : cnt2 ) {
            int s = 0;
            for (int y = x; y <= u; y += x) s += cnt1[y];

            res += 1ll * s * cnt;
        }
        return res;
    }
};
相关推荐
Tisfy1 小时前
LeetCode 3345.最小可整除数位乘积 I:暴力枚举(从n开始尝试)
数学·算法·leetcode·题解·枚举
青山木3 小时前
Hot 100 --- 在排序数组中查找元素的第一个和最后一个位置
java·数据结构·算法·leetcode
mifengxing4 小时前
LeetCode 238 除自身以外数组的乘积|无除法O(n)时间+O(1)空间双解法
java·算法·leetcode
无bug代码搬运工6 小时前
LeetCode 42 接雨水:双指针解法详解
算法·leetcode·职场和发展
zander25810 小时前
34. 在排序数组中查找元素的第一个和最后一个位置:用两个边界定位区间
数据结构·算法·leetcode
To_OC17 小时前
LC 35 搜索插入位置:二分查找谁都会,边界条件谁写谁懵
javascript·算法·leetcode
evans在进步1 天前
LeetCode 189 轮转数组:三次反转原地解决,图解 Java 实现
java·算法·leetcode
旖旎夜光1 天前
LeetCode 991: 坏了的计算器(贪心算法) —— 题解
数据结构·c++·算法·leetcode·贪心算法
旖旎夜光1 天前
LeetCode 553:最优除法(贪心算法) —— 题解
数据结构·c++·算法·leetcode·贪心算法
宵时待雨1 天前
优选算法专题12:队列
算法·leetcode·职场和发展