【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
}
posted @   西*风  阅读(79)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源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 (大正小数相加)
点击右上角即可分享
微信分享提示