📅  最后修改于: 2023-12-03 14:50:37.374000             🧑  作者: Mango
给定一个整数数组和一个正整数 K,计算只包含 K 个不同质数的最长子数组的长度。
例如,给定数组 [2, 5, 7, 8, 10]
和 K=1,只有一个不同质数,那么最长子数组的长度为 3。
这是一道滑动窗口的题目,我们可以使用双指针来表示子数组的左右端点。具体思路如下:
定义两个指针 left 和 right,分别表示子数组的左右端点。
初始化两个变量 count 和 unique 为 0,分别表示子数组中不同质数的个数和出现的不同质数的种类数。
增加 right 指针,将 right 对应的数加入子数组中,并判断该数是否为质数。如果是质数且该质数未出现过,则 unique 加 1;如果不是质数,继续往右扩展。
如果 unique > K,则开始缩小子数组,将 left 指针右移,并从子数组中删除 left 指针对应的数,并判断该数是否为质数。如果是质数且该质数只出现了一次,则 unique 减 1;如果是质数且该质数出现了多次,则只需要将 count 减 1;如果不是质数,则继续缩小。
每次更新 unique 和 count 后,都需要判断是否是最长子数组,如果是则更新最长子数组的长度。
重复步骤 3~5,直到 right 指针走到数组的边界。
以下为 Python 代码实现:
def is_prime(n):
if n < 2:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
def max_subarray_length(nums, K):
left, right = 0, 0
count, unique = {}, 0
ans = 0
while right < len(nums):
num = nums[right]
if is_prime(num):
if num not in count:
unique += 1
count[num] = count.get(num, 0) + 1
while unique > K and left <= right:
num = nums[left]
if is_prime(num):
count[num] -= 1
if count[num] == 0:
unique -= 1
left += 1
ans = max(ans, right - left + 1)
right += 1
return ans
以上代码中,is_prime
函数用于判断一个数是否是质数。时间复杂度为 $O(\sqrt{n})$。
主函数中,使用一个字典 count
记录每个数出现的次数。unique
表示出现的不同质数的种类数。
最后返回 ans
,即为最长子数组的长度。
时间复杂度:$O(n\sqrt{n})$,其中 $n$ 表示数组的长度,is_prime 函数的时间复杂度为 $O(\sqrt{n})$。
空间复杂度:$O(n)$,需要一个字典来记录每个数的出现次数。