问题描述
小R给定了一个整数数组,要求你统计出其中有多少个元素既是素数,且这些素数元素的出现次数也是素数。需要注意的是,数组中元素的出现次数也应计算在内。比如,数组 [1, 2, 3, 2, 5, 7, 7, 7, 5] 中,元素 2 出现了两次,而 7 出现了三次,这些次数也都需要判断是否为素数。
数据结构的选择
- 使用
collections.Counter来统计数组中每个元素的出现次数。 - 使用一个函数来判断一个数是否为素数。
算法步骤
- 统计元素出现次数:使用
Counter(a)来统计数组中每个元素的出现次数。 - 判断素数:编写一个函数
is_prime(n),判断一个数是否为素数。 - 筛选符合条件的元素:遍历统计结果,检查每个元素及其出现次数是否都为素数,如果是,则增加计数。
具体步骤
-
统计元素出现次数:
- 使用
Counter(a)来统计数组中每个元素的出现次数。 - 例如,对于数组
[1, 2, 3, 2, 5, 7, 7, 7, 5],统计结果为{1: 1, 2: 2, 3: 1, 5: 2, 7: 3}。
- 使用
-
判断素数:
-
编写一个函数
is_prime(n),判断一个数是否为素数。 -
素数的判断逻辑:
- 如果
n小于等于 1,返回False。 - 如果
n等于 2,返回True。 - 如果
n是偶数且不等于 2,返回False。 - 对于大于 2 的奇数,检查从 3 到
sqrt(n)之间的数,如果n能被这些数整除,返回False,否则返回True。
- 如果
-
-
筛选符合条件的元素:
- 遍历统计结果,检查每个元素及其出现次数是否都为素数。
- 如果都为素数,则增加计数。
代码实现
def solution(a: list) -> int:
# 统计每个元素的出现次数
count = Counter(a)
# 判断一个数是否为素数的函数
def is_prime(n):
if n <= 1:
return False
if n == 2:
return True
if n % 2 == 0:
return False
for i in range(3, int(n**0.5) + 1, 2):
if n % i == 0:
return False
return True
# 初始化符合条件的元素计数
result = 0
# 遍历统计结果,筛选符合条件的元素
for num, freq in count.items():
if is_prime(num) and is_prime(freq):
result += 1
return result
代码解释
-
统计元素出现次数:使用
Counter(a)来统计数组中每个元素的出现次数。 -
判断素数:实现
is_prime函数,判断一个数是否为素数。具体步骤如下:- 如果
n小于等于 1,返回False。 - 如果
n等于 2,返回True。 - 如果
n是偶数且不等于 2,返回False。 - 对于大于 2 的奇数,检查从 3 到
sqrt(n)之间的数,如果n能被这些数整除,返回False,否则返回True。
- 如果
-
筛选符合条件的元素:遍历
count.items(),检查每个元素及其出现次数是否都为素数,如果是,则增加result的计数。
时间复杂度
-
统计元素出现次数:
- 使用
Counter(a)统计数组中每个元素的出现次数。这个操作的时间复杂度是O(n),其中n是数组的长度。
- 使用
-
判断素数:
- 判断一个数是否为素数的时间复杂度是
O(sqrt(k)),其中k是这个数的大小。 - 对于每个元素及其出现次数,都需要判断是否为素数。假设数组中有
m个不同的元素,那么总共需要判断2m次素数。 - 因此,判断素数的总时间复杂度是
O(m * sqrt(max(a))),其中max(a)是数组中最大的元素。
- 判断一个数是否为素数的时间复杂度是
-
遍历统计结果:
- 遍历统计结果的时间复杂度是
O(m),其中m是不同的元素个数。
- 遍历统计结果的时间复杂度是
综合以上步骤,总的时间复杂度是 O(n + m * sqrt(max(a)))。
空间复杂度
-
统计元素出现次数:
- 使用
Counter(a)统计元素出现次数,需要O(m)的空间,其中m是不同的元素个数。
- 使用
-
其他变量:
- 其他变量(如
result)占用常数空间,可以忽略不计。
- 其他变量(如
综合以上步骤,总的空间复杂度是 O(m)。
总结
- 时间复杂度:
O(n + m * sqrt(max(a))) - 空间复杂度:
O(m)