298.素数元素的统计 | 青训营X豆包MarsCode 技术训练营 | 豆包MarsCode AI 刷题

77 阅读3分钟

题解:298 素数元素的统计

题目

{BB02AC2E-4596-4107-B157-5EFE5733C38F}.png

问题分析

本题要求在一个整数数组中,统计满足以下两个条件的元素个数:

  1. 该元素本身是素数。
  2. 该元素在数组中出现的次数也是素数。

需要特别注意:

  • 需要分别判断数组元素该元素的出现次数是否为素数。
  • 例如,数组 [1, 2, 3, 2, 5, 7, 7, 7, 5] 中,元素 2 出现了两次,而 7 出现了三次。这两次和三次都需要判断是否为素数。

解题思路

  1. 辅助函数:判断素数
    使用一个辅助函数 isPrime,判断一个整数是否为素数:

    • 小于等于 1 的数不是素数。
    • 2 遍历到 sqrt(n),如果 n 能被任何一个数整除,则不是素数。
    • 如果遍历完成没有发现因数,则该数为素数。
  2. 统计数组中每个元素的出现次数
    使用 unordered_map 数据结构来统计每个元素的频率,其中键为数组中的元素,值为该元素的出现次数。

  3. 判断条件
    遍历频率表中的每一对键值对 (num, freq)

    • 检查 num 是否为素数。
    • 检查 freq 是否为素数。
    • 如果两个条件均满足,则计数器加一。
  4. 输出结果
    返回符合条件的元素总数。


代码解析

#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;

// 判断一个数是否为素数
bool isPrime(int n) {
    if (n <= 1) return false; // 小于等于1不是素数
    for (int i = 2; i * i <= n; ++i) { // 遍历到sqrt(n)
        if (n % i == 0) return false; // 存在因数,非素数
    }
    return true; // 无因数,素数
}

int solution(vector<int> a) {
    unordered_map<int, int> frequency; // 统计每个元素的出现次数
    for (int num : a) {
        ++frequency[num]; // 频率加一
    }

    int count = 0; // 计数器
    for (const auto& pair : frequency) {
        int num = pair.first;  // 元素
        int freq = pair.second; // 频率

        // 检查元素和其频率是否都为素数
        if (isPrime(num) && isPrime(freq)) {
            ++count; // 符合条件的元素计数
        }
    }

    return count;
}

int main() {
    cout << (solution({1, 2, 3, 2, 5, 7, 7, 7, 5}) == 3) << endl;
    cout << (solution({1, 4, 6, 8, 10, 12}) == 0) << endl;
    cout << (solution({3, 3, 3, 5, 5, 5, 5}) == 1) << endl;
    return 0;
}

样例说明

样例 1
输入:a = [1, 2, 3, 2, 5, 7, 7, 7, 5]

  1. 频率统计:
    • 1: 出现 1 次
    • 2: 出现 2 次
    • 3: 出现 1 次
    • 5: 出现 2 次
    • 7: 出现 3 次
  2. 检查素数条件:
    • 2 是素数,且出现 2 次也是素数。
    • 3 是素数,且出现 1 次(非素数)。
    • 5 是素数,且出现 2 次也是素数。
    • 7 是素数,且出现 3 次也是素数。
  3. 满足条件的元素有:257,总计 3 个。
    输出:3

样例 2
输入:a = [1, 4, 6, 8, 10, 12]

  1. 频率统计:每个元素出现 1 次。
  2. 检查素数条件:
    • 所有元素均不是素数,直接返回 0。
      输出:0

样例 3
输入:a = [3, 3, 3, 5, 5, 5, 5]

  1. 频率统计:
    • 3: 出现 3 次
    • 5: 出现 4 次
  2. 检查素数条件:
    • 3 是素数,且出现 3 次也是素数。
    • 5 是素数,但出现 4 次(非素数)。
      输出:1

复杂度分析

  1. 时间复杂度

    • 遍历数组统计频率:O(n)
    • 遍历频率表检查素数:O(k * sqrt(m)),其中 k 为频率表中键值对数,m 为键或频率的最大值。
    • 总时间复杂度:O(n + k * sqrt(m))
  2. 空间复杂度
    使用 unordered_map 存储频率,空间复杂度为 O(k)