素数元素的统计(算法解析)| 豆包MarsCode AI刷题

105 阅读4分钟

素数元素的统计

问题描述

小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

题目分析

关键点

  1. 素数判断:需要判断一个数是否为素数。
  2. 元素出现次数统计:需要统计数组中每个元素的出现次数。
  3. 双重素数判断:需要判断元素本身和其出现次数是否都是素数。

解题思路

1. 素数判断

  • 方法: 编写一个函数 isPrime,用于判断一个数是否为素数。

    • 如果数小于等于1,返回 false
    • 如果数等于2,返回 true(因为2是唯一的偶数素数)。
    • 如果数是偶数且不等于2,返回 false
    • 从3开始,逐个检查奇数是否能整除该数,直到 Math.sqrt(num)。如果找到能整除的数,返回 false,否则返回 true

2. 元素出现次数统计

  • 方法: 使用 HashMap 来统计数组中每个元素的出现次数。

    • 遍历数组,对于每个元素,将其出现次数加1。

3. 双重素数判断

  • 方法: 遍历统计结果,对于每个元素及其出现次数,判断它们是否都是素数。

    • 如果元素和其出现次数都是素数,则计数器加1。

算法步骤

  1. 素数判断函数:实现 isPrime 函数。
private static boolean isPrime(int num) {  
    if (num <= 1) return false;  
    if (num == 2) return true; // 2是唯一的偶数素数  
    if (num % 2 == 0) return false; // 其他偶数都不是素数  
    for (int i = 3; i <= Math.sqrt(num); i += 2) {  
        if (num % i == 0) return false;  
    }  
    return true;  
}
  1. 统计元素出现次数:实现 countOccurrences 函数。
private static Map<Integer, Integer> countOccurrences(List<Integer> a) {  
    Map<Integer, Integer> countMap = new HashMap<>();  
    for (int num : a) {  
        countMap.put(num, countMap.getOrDefault(num, 0) + 1);  
    }  
    return countMap;  
}
  1. 主函数

    • 调用 countOccurrences 获取每个元素的出现次数。
    • 遍历统计结果,使用 isPrime 判断元素及其出现次数是否都是素数。
    • 统计符合条件的元素个数并返回。

完整代码:

import java.util.*;

public class Main {
    private static boolean isPrime(int num) {  
        if (num <= 1) return false;  
        if (num == 2) return true; // 2是唯一的偶数素数  
        if (num % 2 == 0) return false; // 其他偶数都不是素数  
        for (int i = 3; i <= Math.sqrt(num); i += 2) {  
            if (num % i == 0) return false;  
        }  
        return true;  
    }  
  
    // 统计数组中每个元素的出现次数  
    private static Map<Integer, Integer> countOccurrences(List<Integer> a) {  
        Map<Integer, Integer> countMap = new HashMap<>();  
        for (int num : a) {  
            countMap.put(num, countMap.getOrDefault(num, 0) + 1);  
        }  
        return countMap;  
    }  
  
    public static int solution(List<Integer> a) {  
        Map<Integer, Integer> countMap = countOccurrences(a);  
        int count = 0;  
        for (Map.Entry<Integer, Integer> entry : countMap.entrySet()) {  
            int element = entry.getKey();  
            int occurrence = entry.getValue();  
            if (isPrime(element) && isPrime(occurrence)) {  
                count++;  
            }  
        }  
        return count;  
    } 

    public static void main(String[] args) {
        System.out.println(solution(Arrays.asList(1, 2, 3, 2, 5, 7, 7, 7, 5)) == 3);
        System.out.println(solution(Arrays.asList(1, 4, 6, 8, 10, 12)) == 0);
        System.out.println(solution(Arrays.asList(3, 3, 3, 5, 5, 5, 5)) == 1);
    }
}

知识点总结:

1. 素数判断

  • 素数的定义:一个大于1的自然数,除了1和它本身外,不能被其他自然数整除的数。

  • 判断素数的方法

    • 基本方法:从2开始,逐个检查是否能整除该数,直到 Math.sqrt(num)

2. 哈希表(HashMap)

  • 定义:哈希表是一种基于键值对的数据结构,能够快速查找、插入和删除元素。

  • 使用场景

    • 统计元素出现次数。
    • 快速查找和更新元素。
  • Java中的实现

    • HashMap<K, V>:键值对的集合,允许键和值为 null
    • put(K key, V value):插入键值对。
    • getOrDefault(K key, V defaultValue):获取键对应的值,如果不存在则返回默认值。

3. 列表(List)

  • 定义:列表是一种有序的集合,可以包含重复元素。

  • 使用场景

    • 存储一组数据。
    • 遍历和操作数据。
  • Java中的实现

    • List<E>:接口,常用实现类有 ArrayList 和 LinkedList
    • Arrays.asList(T... a):将数组转换为列表。

4. 遍历集合

  • 定义:遍历集合是指逐个访问集合中的元素。

  • 使用场景

    • 对集合中的每个元素进行操作。
    • 统计、查找、修改等操作。
  • Java中的实现

    • 增强for循环for (ElementType element : collection)
    • 迭代器Iterator<E>,适用于需要删除元素的场景。

5. 数学函数

  • 定义:数学函数是用于执行数学运算的方法。

  • 使用场景

    • 计算平方根、绝对值、幂等运算等。
  • Java中的实现

    • Math.sqrt(double a):计算平方根。
    • Math.abs(int a):计算绝对值。

该代码通用部分还可应用在其他许多判断素数的场景中。