992. K 个不同整数的子数组
给定一个正整数数组 A,如果 A 的某个子数组中不同整数的个数恰好为 K,则称 A 的这个连续、不一定独立的子数组为好子数组。
(例如,[1,2,3,1,2] 中有 3 个不同的整数:1,2,以及 3。)
返回 A 中好子数组的数目。
解题:双指针
看到子数组,首选双指针,然后暴力解
(两个循环,判断计数)
class Solution:
def subarraysWithKDistinct(self, A: List[int], K: int) -> int:
left = right = tmp = res = 0
sets = set()
while left < len(A):
while (len(sets)) <= K and right < len(A):
sets.add(A[right])
right += 1
if len(sets) == K:
res += 1
sets = set()
left += 1
right = left
return res
但是这并没有通过测试案例,因超出了时间限制
然后我们发现这样的暴力解法确实太粗糙了
(1)首先我们每一次计数前都有一个判断,其实这个判断的条件很大程度上是涵盖在循环的条件里的,这意味着每个小循环都几乎多判断一次
(2)每次移动左指针时我们都重置了右指针即上一轮数据,但其实大可不必,因为K值固定,所以我们可以继承上一轮数据,优化算法
优化:滑动窗口
(这里未给出需要调用的库)
class Solution:
def subarraysWithKDistinct(self, A: List[int], K: int) -> int:
def helper(A, K):
n = len(A)
i = 0
res = 0
diff_nums = 0
counter = collections.defaultdict(int)
for j in range(n):
counter[A[j]] += 1
if counter[A[j]] == 1:
diff_nums += 1
while diff_nums > K:
res += n - j
counter[A[i]] -= 1
if counter[A[i]] == 0:
diff_nums -= 1
i += 1
return res