前缀和题目:
523. 连续的子数组和
所以今天打算练一下前缀和的相关题目,冲啊🐛!
这是这两天的每日一题
前缀和题目入门
前缀和,即利用一个数组sum来记录数组a前i项的和。
可用来求区间和,如求数组a在区间[L,R]的和,那么就是将a[L] 和 a[R] 之间的所有的数相加,但是如果提前知道前L项的和sum[L] 以及前R项的和 sum[R],那么所求的结果就是 sum[L] – sum[R]。这里sum[L] 以及sum[R] 就是前缀和。(leetcode的560题)
利用前缀和可以极大的降低区间查询的时间复杂度
从最经典的定义出发,一般题目会有“连续子数组“ 这一特征
#自己写的前缀和,效率不高
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
#先用O(n)时间累加得到结果
#通常可以与哈希表配合
from collections import defaultdict
presum=0
sum_res=defaultdict(int)
sum_res[0]=1#初始化
res=0
#subset=set()
for num in nums:
#sum_res[presum]+=1
presum+=num
#if presum-k in sum_res:
res+=sum_res[presum-k]
sum_res[presum]+=1
return res
#自己写的前缀和,效率不高
#不调用collections, 速度会快一点
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
#先用O(n)时间累加得到结果
#通常可以与哈希表配合
#from collections import defaultdict
presum=0
sum_res={0:1}
res=0
for num in nums:
presum+=num
if presum-k in sum_res:
res+=sum_res[presum-k]
if presum in sum_res:
sum_res[presum]+=1
else:sum_res[presum]=1
return res
523. 连续的子数组和 (6月2号每日一题)
注意,关键点是子数组大小至少为2!!!
class Solution:
def checkSubarraySum(self, nums: List[int], k: int) -> bool:
#要满足长度为二的限制
modset = set()
presum =0
for num in nums:
presum += num
mod = presum % k
if mod in modset:
return True
modset.add((presum-num)%k)
return False
即要确保set里面只有当前i-2的mod 数目
扩展一下,如果强制要求子数组大小至少为k。这应该怎么做?
class Solution:
def checkSubarraySum(self, nums: List[int], k: int) -> bool:
#要满足长度为二的限制
reqlen=2 # 要满足长度为二的限制
if len(nums)<reqlen:return False
modset = set()
modset.add(0)
presum =sum(nums[:reqlen-1])
target_sum=0
for idx,num in enumerate(nums[reqlen-1:]):
presum += num
mod = presum % k
if mod in modset:
return True
target_sum+=nums[idx]
modset.add((target_sum)%k)
return False
整理了一下电脑,明天应该就到了
晚上八点运动完再来一道 DP:
思路是dp转移方程
dp[i][j]是右下角(i,j)点能有的最大的正方形边
dp[i][j] = min(dp[i][j-1],dp[i-1][j-1],dp[i-1][j])+1
二维动态规划的核心点是找到适合的动态转移方程:
![](https://i-blog.csdnimg.cn/blog_migrate/ac232e11a55fc749cf6100cb1bbcefa8.png)
这道题的思路是先用O(n)时间算出(所有的前缀和)
用的 是 list(accumulate([]) )
这里我们强调一下accumulate 和 reduce的不同:
同时说一下和reduce经常一起出现的 map 和 filter:
![](https://i-blog.csdnimg.cn/blog_migrate/e2d3b7845be04b6e5b506f6d0920be5c.png)
最后再复习一下5月30号的大顶堆:
def sift(li,low,high):
i = low
j= 2*i +1
tmp = li[i]
while j<=high:
if j+1<=high and li[j+1]>li[j]:
j=j+1
if li[j]>tmp:
li[i] = li[j]
i=j
j=2*j+1
else:
break
li[i] = tmp
def heap_sort(li):
m= len(li)
for i in range(m//2-1,-1,-1):
sift(li,i,m-1)
print(li)
for i in range(m-1,-1,-1):
li[0],li[i] = li[i],li[0]
sift(li,0,i-1)
return li
这两天先把每日一题和热题刷完,再刷
https://www.yuque.com/docs/share/4f4d37f2-3ada-42f0-876f-db7b23e479a1?#