【LeetCode】和为k的子数组(map统计前缀和)

和为k的子数组(map统计前缀和)

题目链接:https://leetcode-cn.com/problems/subarray-sum-equals-k/

题目分析:

求和为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
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值