(10)LeetCode 560. 和为K的子数组

LeetCode 560. 和为K的子数组

题目描述

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

示例 1:

复制代码
输入:nums = [1,1,1], k = 2
输出:2

示例 2:

复制代码
输入:nums = [1,2,3], k = 3
输出:2

解题思路

1. 问题转化

假设我们定义前缀和 pre[i] 为数组 nums[0..i] 的和,即
pre[i] = nums[0] + nums[1] + ... + nums[i]

那么,对于任意一个连续子数组 nums[j..i]j ≤ i),它的和可以表示为:
sum(j, i) = pre[i] - pre[j-1](当 j = 0 时,规定 pre[-1] = 0)。

题目要求 sum(j, i) = k,即
pre[i] - pre[j-1] = kpre[j-1] = pre[i] - k

因此,对于每个以 i 结尾的子数组,我们只需要知道在 i 之前 (包括 i 自身吗?注意 j-1 < i,所以是之前)有多少个位置 j-1 的前缀和等于 pre[i] - k。这些位置对应的 j 就是以 i 结尾且和为 k 的子数组的起点。

2. 哈希表优化

我们可以用一个哈希表 hash 来记录遍历过程中每个前缀和出现的次数:

  • 遍历数组,依次计算当前前缀和 cur
  • 对于当前 cur,我们想要知道之前出现过的 cur - k 有多少次,这些次数就是当前 i 结尾的满足条件的子数组个数,累加到答案中。
  • 然后将当前前缀和 cur 的次数加 1,供后续使用。

初始化hash[0] = 1 非常重要。它表示在数组开始之前(即下标 -1 处)有一个虚拟的前缀和为 0。这样当某个 cur == k 时,cur - k = 0 就能从哈希表中取到 1,从而正确统计从下标 0 到 i 的这个子数组。

3. 代码实现细节

原代码将原数组原地修改为前缀和数组,节省了空间。遍历一次并同时更新哈希表和答案。

代码实现(C++)

cpp 复制代码
class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
        int n = nums.size(), ans = 0;
        // 将原数组转化为前缀和数组(原地修改)
        for(int i = 1; i < n; i++)
            nums[i] += nums[i - 1];

        unordered_map<int, int> hash;  // 记录每个前缀和出现的次数
        hash[0] = 1;                    // 初始化:前缀和为0出现1次(空子数组)

        for(int i = 0; i < n; i++){
            // 当前前缀和减去k,得到需要的前缀和值
            ans += hash[nums[i] - k];
            // 将当前前缀和的计数加1
            hash[nums[i]]++;
        }
        return ans;
    }
};

复杂度分析

  • 时间复杂度O(n),其中 n 是数组的长度。我们只需遍历数组两次(一次计算前缀和,一次遍历统计),哈希表的插入和查询都是 O(1)
  • 空间复杂度O(n),哈希表在最坏情况下需要存储所有不同的前缀和。

总结

本题是前缀和与哈希表结合的经典题目。核心思想是将子数组和问题转化为两个前缀和的差值问题,利用哈希表快速查找之前出现过的前缀和,从而在一次遍历中完成统计。初始化 hash[0] = 1 是处理从数组开头开始的子数组的关键。

拓展

  • 如果题目要求返回所有满足条件的子数组的具体下标,则可以在哈希表中存储前缀和对应的下标列表,然后遍历输出。
  • 如果数组中有负数,前缀和可能不是单调的,但该算法依然适用,因为哈希表只关心值出现的次数,不关心顺序。
相关推荐
江畔柳前堤33 分钟前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Forever Nore2 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考3 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX4 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面5 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号5 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽5 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI5 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
地平线开发者7 小时前
征程6工具链模型X86推理方式说明
算法
地平线开发者7 小时前
【征程6】校准量化中HistogramObserver解析
算法