📜  只有 K 个不同质数的最长子数组的长度(1)

📅  最后修改于: 2023-12-03 14:50:37.374000             🧑  作者: Mango

题目介绍

给定一个整数数组和一个正整数 K,计算只包含 K 个不同质数的最长子数组的长度。

例如,给定数组 [2, 5, 7, 8, 10] 和 K=1,只有一个不同质数,那么最长子数组的长度为 3。

解题思路

这是一道滑动窗口的题目,我们可以使用双指针来表示子数组的左右端点。具体思路如下:

  1. 定义两个指针 left 和 right,分别表示子数组的左右端点。

  2. 初始化两个变量 count 和 unique 为 0,分别表示子数组中不同质数的个数和出现的不同质数的种类数。

  3. 增加 right 指针,将 right 对应的数加入子数组中,并判断该数是否为质数。如果是质数且该质数未出现过,则 unique 加 1;如果不是质数,继续往右扩展。

  4. 如果 unique > K,则开始缩小子数组,将 left 指针右移,并从子数组中删除 left 指针对应的数,并判断该数是否为质数。如果是质数且该质数只出现了一次,则 unique 减 1;如果是质数且该质数出现了多次,则只需要将 count 减 1;如果不是质数,则继续缩小。

  5. 每次更新 unique 和 count 后,都需要判断是否是最长子数组,如果是则更新最长子数组的长度。

  6. 重复步骤 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)$,需要一个字典来记录每个数的出现次数。