LeetCode(python)——560.和为k的子数组

题目

给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 

子数组是数组中元素的连续非空序列。

示例 1:

输入:nums = [1,1,1], k = 2
输出:2

示例 2:

输入:nums = [1,2,3], k = 3
输出:2

思路

(1)前缀和——pre[i]定义为数组前i个元素的和

如果已知每个下标的前缀和,那么[i....j-1]这个子数组的和为k,则意味着pre[j] - pre[i] == k,左右变换一下可以得到:pre[i] = pre[j] - k

非常好,那么我们就可以在遍历数组计算每个下标前缀和的时候,计算target = pre[j] - k,如果已经记录的前缀和pre[i] == target,就说明对于pre[j]而言,找到了一个子数组[i....j-1]

(2)哈希表

在找前缀和pre[i]时,可以不用数组存,那么也就可以不用再遍历一遍前缀和了

用哈希表存,key = pre[i],value = pre[i]出现的次数

A tip:

数组有序——滑动窗口

数组无序——前缀和

代码

class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
        ans = 0
        pre = 0
        mp = {0: 1}   # 初始化pre[0],以备出现从头开始的子数组计算eg:pre[i]==k,那么pre[i]-k=0,要找的前缀和就是0
        for num in nums:
            pre += num   # 计算前缀和
            target = pre - k   # 计算满足条件的前缀和
            ans = ans + mp.get(target, 0)   # 记录答案
            mp[pre] = mp.get(pre, 0) + 1   # 记录当前的前缀和
        return ans

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值