好子数组的计数| 豆包MarsCode AI刷题

52 阅读3分钟

问题描述 小M有一个由正整数组成的数组 nums,她想知道其中有多少子数组可以被称为「好子数组」。一个子数组被称为「好子数组」是指它包含的不同整数个数恰好为 k。 例如,对于数组 [1, 2, 3, 1, 2],其中包含 3 个不同的整数:1、2 和 3。 子数组指的是数组的连续部分。小M需要找出所有满足条件的子数组,并计算它们的数量。

测试样例 样例1: 输入:nums = [1, 2, 1, 2, 3],k = 2 输出:7 样例2: 输入:nums = [1, 2, 1, 3, 2],k = 3 输出:5 样例3: 输入:nums = [1, 1, 1, 1],k = 1

def solution(nums: list, k: int) -> int: n = len(nums) count = 0

for i in range(n):
    distinct_nums = set()
    for j in range(i, n):
        distinct_nums.add(nums[j])
        if len(distinct_nums) == k:
            count += 1
        elif len(distinct_nums) > k:
            break

return count

if __name__ == '__main__':
print(solution(nums=[1, 2, 1, 2, 3], k=2) == 7)
print(solution(nums=[1, 2, 1, 3, 2], k=3) == 5)
print(solution(nums=[1, 1, 1, 1], k=1) == 10)

在上述代码中:

  • 我们使用两层循环来遍历所有可能的子数组。外层循环i确定子数组的起始位置,内层循环j从起始位置i开始逐步扩展子数组的末尾位置。

  • 对于每个子数组,我们使用一个集合distinct_nums来记录其中出现的不同整数。当集合中不同整数的个数等于k时,就找到了一个满足条件的好子数组,此时计数器count加 1。如果不同整数的个数超过了k,就无需继续扩展该子数组了,直接进入下一个起始位置i的循环。

  • 最后,返回计数器count的值,即为满足条件的好子数组的数量。

  • 不过,这种方法的时间复杂度是 ,在某些情况下可能效率不高。我们可以进一步优化,使用哈希表和双指针的方法来将时间复杂度降低到 ,以下是优化后的代码:

收起

python

复制

from typing import List


def solution(nums: List[int], k: int) -> int:
    n = len(nums)
    count = 0
    left = 0
    right = 0
    distinct_count = 0
    num_count = {}

    while right < n:
        if nums[right] not in num_count:
            num_count[nums[right]] = 1
            distinct_count += 1
        else:
            num_count[nums[right]] += 1

        while distinct_count > k:
            num_count[nums[left]] -= 1
            if num_count[nums[left]] == 0:
                distinct_count -= 1
                del num_count[nums[left]]
            left += 1

        if distinct_count == k:
            count += right - left + 1

        right += 1

    return count

在优化后的代码中:

  • 我们使用双指针leftright来表示滑动窗口的左右边界。
  • num_count是一个哈希表,用于记录每个数字在当前窗口中出现的次数。distinct_count则记录当前窗口中不同数字的个数。
  • 当右指针right向右移动时,我们更新num_countdistinct_count。如果distinct_count超过了k,我们通过移动左指针left来缩小窗口,直到distinct_count等于k为止。
  • distinct_count等于k时,满足条件的子数组数量就增加right - left + 1,因为从leftright的这个窗口内的所有子数组(以left为起始位置,长度从 1 到right - left + 1)都满足条件。
  • 最后返回count,就是满足条件的好子数组的总数。这种优化后的方法时间复杂度为 ,其中n是数组nums的长度,在处理较大规模的数组时效率更高。