素数元素的统计
问题描述
小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. 素数判断
-
方法: 编写一个函数
isPrime,用于判断一个数是否为素数。- 如果数小于等于1,返回
false。 - 如果数等于2,返回
true(因为2是唯一的偶数素数)。 - 如果数是偶数且不等于2,返回
false。 - 从3开始,逐个检查奇数是否能整除该数,直到
Math.sqrt(num)。如果找到能整除的数,返回false,否则返回true。
- 如果数小于等于1,返回
2. 元素出现次数统计
-
方法: 使用
HashMap来统计数组中每个元素的出现次数。- 遍历数组,对于每个元素,将其出现次数加1。
3. 双重素数判断
-
方法: 遍历统计结果,对于每个元素及其出现次数,判断它们是否都是素数。
- 如果元素和其出现次数都是素数,则计数器加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;
}
- 统计元素出现次数:实现
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;
}
-
主函数:
- 调用
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开始,逐个检查是否能整除该数,直到
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>,适用于需要删除元素的场景。
- 增强for循环:
5. 数学函数
-
定义:数学函数是用于执行数学运算的方法。
-
使用场景:
- 计算平方根、绝对值、幂等运算等。
-
Java中的实现:
Math.sqrt(double a):计算平方根。Math.abs(int a):计算绝对值。
该代码通用部分还可应用在其他许多判断素数的场景中。