【LeetCode】和为k的子数组(map统计前缀和)
和为k的子数组(map统计前缀和)
题目链接:https://leetcode-cn.com/problems/subarray-sum-equals-k/
给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。
示例 1:
输入:nums = [1,1,1], k = 2
输出:2
示例 2:
输入:nums = [1,2,3], k = 3
输出:2
提示:
1 <= nums.length <= 2 * 104
-1000 <= nums[i] <= 1000
-107 <= k <= 107
题目分析:
求和为k的子数组数量
我们从暴力解法一步步推导
1.首先最基础的暴力是三层循环,两层分别确定区间起始点,最后一层计算此区间和是否为k,时间复杂度为O(N * N * N)
2.改进一下,简化最后一层循环,用前缀和来计算每次的区间和,时间复杂度:O(N*N)
3.我们起始不需要知道满足要求的子数组到底是哪些,只要知道到底有多少个符合要求的子数组即可
- 我们知道每个元素都对应一个前缀和preSum,在遍历数组得到某个元素i的前缀和preSum[i]的时候,如果i之前存在一个历史前缀和,使得当前前缀和减去历史前缀和等于k(即preSum[i]-preSum[j-1]==k),那么此子数组符合要求,计数+1
- 所以我们只需要在遍历数组时,利用一个map记录下每个元素的前缀和,再每次统计看有没有符合要求的历史前缀和即可
- 时间复杂度:O(N),空间复杂度:O(N)
func subarraySum(nums []int, k int) int {
preSum:=0 // 前缀和
mPreSum:=make(map[int]int) // 统计某一个值的前缀和出现次数
mPreSum[0]=1 // 前缀和为0的子数组 出现了一次 ,让下标-1位置对应的前缀和为0
count:=0 // 计数器,每次统计符合要求的历史前缀和,即符合要求的子数组数量
for i:=0;i<len(nums);i++{
preSum+=nums[i] // 对每个元素,更新前缀和
// 判断此时有没有符合要求的历史前缀和,有则统计
if _,ok:=mPreSum[preSum-k];ok{
count+=mPreSum[preSum-k]
}
// 值为preSum的前缀和出现次数+1
mPreSum[preSum]++
}
return count
}
心之所向,素履以往
分类:
LeetCode
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
2018-04-09 调度算法之最短作业优先算法
2018-04-09 HDU1027
2018-04-09 HDU1753 (大正小数相加)