题目:
给定一个正整数数组 A,如果 A 的某个子数组中不同整数的个数恰好为 K,则称 A 的这个连续、不一定独立的子数组为好子数组。
(例如,[1,2,3,1,2] 中有 3 个不同的整数:1,2,以及 3。)
返回 A 中好子数组的数目。
思路:
atMostK(self,A,K):A中 至多有K个不同整数的子数组 的数目
所求即为:atMosK(A, K)-atMostK(A,K-1)
atMostK(A,K)的求解 利用了滑动窗口的思想。
若A= [1,2,1,2],K=2,则 A中至多有K个不同整数的子数组 包括:
[1]
[1,2],[2]
[1,2,1],[2,1],[1]
[1,2,1,2],[2,1,2],[1,2],[2]
其个数为:1+2+3+4=10
当前滑动窗口的长度为几,滑动窗口所包含的子数组就为几。
解答:
class Solution:
def subarraysWithKDistinct(self, A: List[int], K: int) -> int:
return self.atMostK(A, K) - self.atMostK(A, K - 1)
def atMostK(self,A,K):
n=len(A)
left=0
right=0
counter=collections.Counter()
#distinct记录字典counter中不同整数的个数
distinct=0
#res记录A中 不同整数的个数至多为k 的子数组 的数目
res=0
#滑动窗口
while right<n:
if counter[A[right]]==0:
distinct+=1
counter[A[right]]+=1
while distinct>K:
counter[A[left]]-=1
if counter[A[left]]==0:
distinct-=1
left+=1
#累加当前窗口所含的子数组
res+=right-left+1
print(left,right,res)
right+=1
return res