问题描述
小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)