标签:cnt 992 int res 整数 most len 数组
给定一个正整数数组 A
,如果 A
的某个子数组中不同整数的个数恰好为 K
,则称 A
的这个连续、不一定独立的子数组为好子数组。
(例如,[1,2,3,1,2]
中有 3
个不同的整数:1
,2
,以及 3
。)
返回 A
中好子数组的数目。
示例 1:
输入:A = [1,2,1,2,3], K = 2 输出:7 解释:恰好由 2 个不同整数组成的子数组:[1,2], [2,1], [1,2], [2,3], [1,2,1], [2,1,2], [1,2,1,2].
示例 2:
输入:A = [1,2,1,3,4], K = 3 输出:3 解释:恰好由 3 个不同整数组成的子数组:[1,2,1,3], [2,1,3], [1,3,4].
提示:
1 <= A.length <= 20000
1 <= A[i] <= A.length
1 <= K <= A.length
双循环滑动窗口
TLE 40/55
class Solution: def subarraysWithKDistinct(self, A: List[int], K: int) -> int: curLen=0 res=0 for i in range(len(A)): cnt=0 for j in range(i,len(A)): curLen=len(set(A[i:j+1])) if curLen==K: res+=1 elif curLen>K: break return res
运用哈希表,双指针继续莽
wa
class Solution: def subarraysWithKDistinct(self, A: List[int], K: int) -> int: res=0 i=j=0 cnt=collections.defaultdict(int) while True: while j<len(A) and len(cnt)<=K: cnt[A[j]]+=1 j+=1 if len(cnt)==K:res+=1 while i<len(A) and len(cnt)>K: cnt[A[i]]-=1 if cnt[A[i]]==0:del cnt[A[i]] i+=1 if len(cnt)==K:res+=1 if i>=len(A) or j>=len(A):break while i<len(A): cnt[A[i]]-=1 if cnt[A[i]]==0:del cnt[A[i]] i+=1 if len(cnt)==K:res+=1 return res
其实移动双指针的时候,可以计算不超过K的,then K=
cnt_at_most(K)-cnt_at_most(K-1)
class Solution: def subarraysWithKDistinct(self, A: List[int], K: int) -> int: def cnt_at_most(K): res=0 i=j=0 cnt=collections.defaultdict(int) while True: #在子数组中不同整数的个数<=K的情况下j指针向右扩张 while j<len(A) and len(cnt)<=K: #对A[j]加1 cnt[A[j]]+=1 #移动指针 j+=1 #满足cnt_at_most(K),res加上j-i if len(cnt)<=K:res+=j-i #在子数组中不同整数的个数>K的情况下i指针向右扩张 while i<len(A) and len(cnt)>K: #对A[i]减1 cnt[A[i]]-=1 #cnt为0时删除 if cnt[A[i]]==0:del cnt[A[i]] #移动指针 i+=1 #满足cnt_at_most(K),res加上j-i if len(cnt)<=K:res+=j-i if j>=len(A):break return res #cnt_at_most(K)-cnt_at_most(K-1)即为答案 return cnt_at_most(K)-cnt_at_most(K-1)
我们再回到第一个解法
如何降维?
经过一番探索发现Google,可以写出这样的解法
class Solution: def subarraysWithKDistinct(self, A: List[int], K: int) -> int: cnt = {} res = i = diffNum = leftForward = 0 for j in range(len(A)): if A[j] not in cnt: diffNum += 1 cnt[A[j]] = 1 else: cnt[A[j]] +=1 if diffNum == K: #当A[i-1] != A[j] and i > 0 的时候置 leftForward 为 0 if A[i-1] != A[j] and i > 0: leftForward = 0 #在子数组中不同整数的个数恰好为 K 的情况下i指针向右移动 while diffNum == K: #注意cnt[A[i]] == 1的情况 if cnt[A[i]] == 1: diffNum -= 1 del cnt[A[i]] else: cnt[A[i]] -= 1 i += 1 leftForward += 1 res += leftForward return res
标签:cnt,992,int,res,整数,most,len,数组 来源: https://www.cnblogs.com/xxxsans/p/14392328.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。