【LeetCode每日一题】560. 和为 K 的子数组串


2025.8.18

560. 和为 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

总体思路

暴力求解

  • 枚举所有子数组:
    外层循环固定子数组的起点 i。
    内层循环枚举子数组的终点 j。
  • 逐步累加:
    从 i 到 j 的元素累加求和,看是否等于 k。
  • 计数:
    如果和等于 k,就让 count++。
  • 时间复杂度:O(n²)

前缀和 + 哈希表

  • 前缀和定义:
    pre[i] = nums[0] + nums[1] + … + nums[i]。
    任意子数组和 nums[l…r] = pre[r] - pre[l-1]。
    所以我们只要知道某个前缀和 pre[r]-k 之前出现过几次,就能知道有多少个子数组以 r 为结尾,和等于 k。
  • 哈希表 m:
    • key:某个前缀和的值
    • value:这个前缀和出现的次数
  • 初始化:
    m[0] = 1,表示“前缀和 0 出现过 1 次”,这样当 pre == k 时,能正确计数从 0 开始的子数组。
  • 遍历数组:
    • 更新当前前缀和:pre += nums[i]
    • 在哈希表里查找:pre-k 出现过多少次,把次数加到答案上。
    • 把当前前缀和 pre 存入哈希表(出现次数 +1)。
  • 时间复杂度:O(n)

代码

golang

//暴力求解
func subarraySum(nums []int, k int) int {
    n := len(nums)
    count := 0
    for i:=0; i<n; i++ {
        sum := nums[i]
        if sum == k {
            count++
        }
        for j:=i+1; j<n; j++ {
            sum += nums[j]
            if sum == k {
                count++
            }
        }
    }
    return count
}

// 前缀和+哈希表
// 统计和为 k 的子数组个数:前缀和 + 哈希表
func subarraySum(nums []int, k int) int {
    n := len(nums)
    count, pre := 0, 0

    // 方式一:字面量初始化并预置 m[0]=1,表示前缀和为 0 出现过 1 次
    // m 的含义:m[x] 表示“前缀和等于 x 的出现次数”
    m := map[int]int{0: 1}

    for i := 0; i < n; i++ {
        pre += nums[i]                  // 维护当前前缀和
        // 需要的“目标前缀和”是 pre-k,出现几次就能形成几个子数组
        count += m[pre-k]               // 若不存在,m[pre-k] 默认是 0(见下文语法点)
        /*if _, ok := m[pre - k]; ok {
            count += m[pre - k]  
        }*/ //不必要写这一步
        m[pre] = m[pre] + 1             // 记录当前前缀和出现次数 +1
    }
    return count
}
// 前缀和+哈希表,无注释版本
func subarraySum(nums []int, k int) int {
    n:=len(nums)
    count:=0
    pre:=0
    m := map[int]int{0:1}
    for i:=0;i<n;i++ {
        pre+=nums[i]
        count+=m[pre-k]
        m[pre]+=1
    }
    return count
}

golang知识

  • map 默认值特性
    count += m[pre-k] 这一句很妙。
    在其他语言(比如 Java、C++)里,访问不存在的 key 会报错或需要额外判断。
    在 Go 里,访问不存在的 key 会返回“零值”,这里是 0。
    所以可以少写 if 判断,代码更简洁。

  • 预置 m[0] = 1
    这是算法的小技巧。
    它让“从下标 0 开始的子数组”也能被统计到,否则会漏掉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值