6月1日 儿童节快乐!!! 前缀和 (6月2号更新因为这两天都是前缀和问题就放在一起了)...

前缀和题目:

1744. 你能在你最喜欢的那天吃到你最喜欢的糖果吗?

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题)
利用前缀和可以极大的降低区间查询的时间复杂度

从最经典的定义出发,一般题目会有“连续子数组“ 这一特征

560. 和为K的子数组

#自己写的前缀和,效率不高
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:

221. 最大正方形

思路是dp转移方程

dp[i][j]是右下角(i,j)点能有的最大的正方形边

dp[i][j] = min(dp[i][j-1],dp[i-1][j-1],dp[i-1][j])+1

二维动态规划的核心点是找到适合的动态转移方程:

1744. 你能在你最喜欢的那天吃到你最喜欢的糖果吗?

这道题的思路是先用O(n)时间算出(所有的前缀和)

用的 是 list(accumulate([]) )

这里我们强调一下accumulate 和 reduce的不同:

同时说一下和reduce经常一起出现的 map 和 filter:

最后再复习一下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?#

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值