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