LeetCode 560题:和为K子数组最优解

题目理解

给定整数数组nums和整数k,统计连续非空 子数组中和为k的个数。

  • 示例 1:nums = [1,1], k=2 → 输出 2([1,1][1(第二个)]
  • 示例 2:nums = [1,2,3], k=3 → 输出 2([1,2][3]

解法 1:暴力前缀和(超时预警)

首先想到前缀和数组的基础思路:

  1. 构造前缀和数组v,其中v[i]表示nums[0..i-1]的和(v[0]=0v[1]=nums[0],以此类推)
  2. 任意子数组nums[j..i-1]的和 = v[i] - v[j],遍历所有i>j,统计v[i]-v[j]==k的次数

代码如下:

cpp

运行

复制代码
int subarraySum(vector<int>& nums, int k) {
    vector<int> v(nums.size()+1);
    int count=0;
    // 构造前缀和数组
    for(int i=1;i<=nums.size();++i) {
        v[i] = v[i-1] + nums[i-1];
    }
    // 遍历所有i>j的组合
    for(int i=1;i<=nums.size();++i) {
        for(int j=0;j<i;++j) {
            if(v[i]-v[j] == k) count++;
        }
    }
    return count;
}

但这个方法的时间复杂度是O(n²),对于n=2e4的用例来说会超时,必须优化。

解法 2:前缀和 + 哈希表(O (n) 时间)

核心思路是用哈希表记录前缀和出现的次数,避免二次遍历:

  1. 维护一个变量sum,表示当前遍历到的前缀和(代替前缀和数组)
  2. 用哈希表hash存储前缀和的值 → 出现的次数 ,初始化hash[{0,1}](对应前缀和为 0 的情况,防止第一个元素就是 k 的情况)
  3. 遍历数组时:
    • 累加sum得到当前前缀和
    • sum - k在哈希表中存在,说明存在前缀和为sum-k的子数组,其到当前位置的子数组和为 k,将次数累加到结果
    • 将当前前缀和sum的出现次数存入哈希表

优化后的代码:

cpp

运行

复制代码
int subarraySum(vector<int>& nums, int k) {
    unordered_map<int, int> hash = {{0, 1}}; // 初始化前缀和0出现1次
    int ret = 0, sum = 0;
    for (int e : nums) {
        sum += e; // 当前前缀和
        // 统计有多少个前缀和等于sum-k
        if (hash.count(sum - k)) {
            ret += hash[sum - k];
        }
        hash[sum]++; // 记录当前前缀和的出现次数
    }
    return ret;
}

为什么这样能行?

举个例子(nums=[1,1],k=2):

  • 初始化:sum=0hash={0:1}
  • 遍历第一个 1:sum=1sum-k=-1不在 hash 中 → hash[1]设为 1
  • 遍历第二个 1:sum=2sum-k=0在 hash 中(次数 1)→ ret=1,再将hash[2]设为 1
  • 最终ret=2,和示例结果一致

总结

  • 暴力前缀和:时间O(n²),空间O(n)(超时)
  • 前缀和 + 哈希表:时间O(n),空间O(n)(最优解)
相关推荐
qq_401700412 小时前
C/C++中的signed char和unsigned char详解
c语言·c++·算法
leoufung2 小时前
LeetCode 67. Add Binary:从面试思路到代码细节
算法·leetcode·面试
wjykp3 小时前
79~87逻辑回归f
算法·机器学习·逻辑回归
聆风吟º3 小时前
【顺序表习题|图解|双指针】合并两个有序数组 + 训练计划 I
c语言·数据结构·c++·经验分享·算法
wa的一声哭了3 小时前
矩阵分析 方阵幂级数与方阵函数
人工智能·python·线性代数·算法·自然语言处理·矩阵·django
菩提祖师_3 小时前
基于MATLAB的心电信号处理与心律异常检测算法设计
算法·matlab·信号处理
foundbug9993 小时前
用ode45求解悬臂梁的动力学方程,得到其变形
算法
linsa_pursuer3 小时前
最长连续序列
java·数据结构·算法·leetcode
wa的一声哭了3 小时前
矩阵分析 单元函数矩阵微积分和多元向量值的导数
linux·c语言·c++·线性代数·算法·矩阵·云计算