素数元素统计 | 豆包MarsCode AI刷题

139 阅读3分钟

题目介绍

问题描述

小R给定了一个整数数组,要求你统计出其中有多少个元素既是素数,且这些素数元素的出现次数也是素数。需要注意的是,数组中元素的出现次数也应计算在内。比如,数组 [1, 2, 3, 2, 5, 7, 7, 7, 5] 中,元素 2 出现了两次,而 7 出现了三次,这些次数也都需要判断是否为素数。

测试样例

样例1:

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

样例2:

输入:a = [1, 4, 6, 8, 10, 12]
输出:0

样例3:

输入:a = [3, 3, 3, 5, 5, 5, 5]
输出:1

思路描述

初步思考

题目中要求有一个数组,需要我们进行统计元素本身也是素数,同时元素出现的次数也要是素数,满足这两个条件的时候才可以算上一次统计的条件,然后需要我们统计整个数组中的这样数组出现的情况。初次见到的时候觉得题目还是比较简单的,虽然是一个中等的题目,但是细致思考下可以发现整个题目还有有借鉴意义,可以更加熟悉素数和一些编程思想

深入思考

首先对于数组的处理其实一直以来都是遍历就可以,然后对于数组中的数据进行单独的处理。其实这个题目也不例外,也同样是这样的处理思路,但是我们还需要注意一个条件就是需要统计元素出现的次数,这个也是作为一个判定条件。那么就需要一个数据结构来维护这个元素和次数关系的映射,我们很自然的就想到了map这个数据结构,c++中不考虑排序,用unordered_map就可以完成映射,其底层实现的机制为红黑树,可以达到o(n)的速度。我们首先去遍历数组,并且对每一个元素映射到map中,这样遍历的时候,如果不存在就开辟一个新的映射,存在就累加。那么我们就相当于获取了数据加次数两个元素。然后再进行素数判断。 素数判断的时候,可以用埃氏筛选法,或者用最为传统的方法,也就是根据定义,只能被自己或者1整除。那么判断函数的逻辑就是从2开始遍历到自己前一个元素为止,如果可以被整除说明不是素数,不然就是。当然根据数学原理,也可以只判断到自己开根号为止,可以减少判断次数。然后遍历map映射,判断是不是素数,统计次数,最后返回结果。 直接上代码。

代码

bool isSu(int num) {
    if (num == 2 || num == 3) return true;
    if (num == 1) return false;
    for (int i = 2 ; i <= sqrt(num); i++) {
        if (num % i == 0) return false;
    }
    return true;
}

int solution(vector<int> a) {
    int res = 0;
    unordered_map<int, int> myMap;
    for (int i = 0; i < a.size(); i++) {
        myMap[a[i]]++;
    }
    for (const auto&pair : myMap) {
        if (isSu(pair.first) && isSu(pair.second)) res++;
    }
    // cout<<res<<endl;
    return res;
}