classSolution:defsubarraySum(self, nums: List[int], k:int)->int:presum =[0]*(len(nums)+1)for i, x inenumerate(nums):presum[i +1]= presum[i]+ x # 前缀和序列需要n+1个ans =0cnt = defaultdict(int)for p in presum:ans += cnt[p - k]cnt[p]+=1return ans
二、239. 滑动窗口最大值
思路1:暴力。这道题如果暴力求解其实很简单,根据描述写就行了,但是复杂度比较高, O ( n 2 ) O(n^2) O(n2)
代码
classSolution:defmaxSlidingWindow(self, nums: List[int], k:int)-> List[int]:iflen(nums)==1:return numsres =[]left, right =0, kwhile left <=(len(nums)-k):res.append(max(nums[left:right]))left+=1right+=1return res
思路2:单调队列。单调队列分为3步
入(元素入队尾,并维护单调性(看需要保持单增,还是单减))
出(元素离开队首)
记录答案
代码
classSolution:defmaxSlidingWindow(self, nums: List[int], k:int)-> List[int]:ans =[]q = deque()for i, x inenumerate(nums):# 入while q and nums[q[-1]]<= x:q.pop()# 删除比x小的元素(找最大值,比x小的就不用看了)q.append(i)# 加入到队尾(这个队列也是单调的了)# 出if i - q[0]>= k:# 队首需要离开了(滑窗滑过了)q.popleft()# 记录if i >= k -1:ans.append(nums[q[0]])retrun ans