题解:洛谷 P15799 找数

【题目来源】

洛谷:P15799 [GESP202603 五级] 找数 - 洛谷

【题目描述】

给定一个包含 \(n\) 个互不相同的正整数的数组 \(A\) 与一个包含 \(m\) 个互不相同的正整数的数组 \(B\),请你帮忙计算有多少个数在数组 \(A\) 与数组 \(B\) 中均出现。

【输入】

第一行包含两个整数 \(n,m\)

第二行包含 \(n\) 个正整数 \(a_1,a_2,\cdots,a_n\) 表示数组 \(A\)

第三行包含 \(m\) 个正整数 \(b_1,b_2,\cdots,b_m\) 表示数组 \(B\)

【输出】

输出一个整数,表示在数组 \(A\) 与数组 \(B\) 中均出现的数的个数。

【输入样例】

3 5
4 2 3
3 1 5 4 6

【输出样例】

2

【核心思想】

  1. 问题分析:给定两个互不相同正整数组成的数组 \(A\)(长度 \(n\))和 \(B\)(长度 \(m\)),需要统计同时在两个数组中出现的数的个数。本质是集合交集大小的计算问题。由于两个数组内部元素互不相同,每个数在每个数组中最多出现一次。

  2. 算法选择

    • 哈希表(map)计数:将两个数组的所有元素放入同一个频率表中,出现次数为 \(2\) 的即为交集元素
    • 集合交集思想:利用"元素互不相同"的条件,通过频率统计替代显式集合操作
  3. 关键步骤

    • 初始化:创建频率表 mp
    • 录入数组 \(A\):遍历 \(A\) 的每个元素 \(x\),执行 mp[x]++
    • 录入数组 \(B\):遍历 \(B\) 的每个元素 \(x\),执行 mp[x]++
    • 统计交集:遍历 mp 中的每个键值对 \((k, v)\)
      • \(v = 2\),说明该数在两个数组中各出现一次,ans++
    • 输出结果\(ans\)
  4. 时间/空间复杂度

    • 时间复杂度:\(O((n + m) \log(n + m))\),每次 map 插入和查询为 \(O(\log(n + m))\)
    • 空间复杂度:\(O(n + m)\),存储所有不同元素的频率
  5. 哈希表求交集的核心思想

    • 频率即交集标记:由于两个数组内部均无重复元素,若某数在两个数组中都出现,则其在 mp 中的计数恰好为 \(2\)。利用这一性质,无需显式比较两个集合,通过一次频率统计即可判定交集
    • 合并统计策略:将两个数组的元素统一放入一个频率表,而非分别存储再比对,减少空间开销和比较次数
    • 键的唯一性map 的键自动去重,天然适合处理"互不相同"的集合元素,避免了重复元素的干扰
    • 可扩展性:若数组内部允许重复,需调整判定条件(如 \(v \geq 2\) 或使用 set 去重后再统计),但本题条件简化了逻辑
    • 适用于集合交集、并集、差集等基础集合运算问题,尤其是元素范围较大或离散的场景

【算法标签】

普及- #哈希表

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 100005;

int n, m;
int ans;
// 使用 map 记录每个数字出现的次数
map<int, int> mp;

int main()
{
    cin >> n >> m;
    // 读入第一个集合的元素
    for (int i = 1; i <= n; i++)
    {
        int x;
        cin >> x;
        // 记录第一个集合中数字的出现次数
        mp[x]++;
    }
    // 读入第二个集合的元素
    for (int i = 1; i <= m; i++)
    {
        int x;
        cin >> x;
        // 记录第二个集合中数字的出现次数
        mp[x]++;
    }
    // 遍历 map
    for (auto x : mp)
    {
        // 如果某个数字出现了两次,说明在两个集合中都出现过
        if (x.second == 2)
        {
            ans++;
        }
    }
    // 输出交集的大小
    cout << ans << endl;
    return 0;
}

【运行结果】

3 5
4 2 3
3 1 5 4 6
2
posted @ 2026-07-01 21:37  团爸讲算法  阅读(18)  评论(0)    收藏  举报