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)(最优解)
相关推荐
大明者省6 小时前
WSL2 Ubuntu22.04 GPU训练环境配置指南
人工智能·算法·计算机视觉
白狐_7987 小时前
408数据结构第8章:排序②——性质对比秒杀、场景选择与外部排序
java·数据结构·算法
zander2588 小时前
LeetCode 84:柱状图中的最大矩形——单调栈如何确定左右边界
java·数据结构·算法
Shell运维手记8 小时前
Linux 常用基础命令学习笔记
linux·运维·笔记·学习·算法·github
杨航 AI8 小时前
O(n log n):线性对数原理拆解 这个是排序算法的黄金复杂度之一。
算法·排序算法
船厂电气自动化ai大模型9 小时前
AI大模型与数学 第32课 函数凹凸性与二阶导数:拐点求解、凹凸区间计算(10道二阶导数计算题)
数据结构·人工智能·python·深度学习·算法
旖旎夜光9 小时前
LeetCode 3:无重复字符的最长子串(滑动窗口) —— 题解
数据结构·c++·算法·leetcode·滑动窗口
叠层归一研究院10 小时前
AGI 系统(十一):二阶网络 — 二阶递归 × 多主体 (元符号网络)
开发语言·人工智能·算法·php·agi
zlinear数据采集卡11 小时前
D223的PWM电机控制:6路独立脉冲+加减速算法深度解析
arm开发·stm32·嵌入式硬件·算法·fpga开发·架构
杨石兴11 小时前
31、玩具MoM:用2x2矩阵串起全套流程
人工智能·算法·矩阵·电磁学