【LeetCode热题100】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 ∗ 1 0 4 2 * 10^4 2∗104

-1000 <= nums[i] <= 1000
− 1 0 7 -10^7 −107 <= k <= 1 0 7 10^7 107

四.解题思路

解法1:暴力穷举

解法2:前缀和 + 哈希表

优化思路

前缀和(Prefix Sum):这是一种常用的技巧,可以快速计算任意区间内的元素和。我们遍历数组,计算从第一个元素到当前元素的总和,并将这个总和保存起来作为前缀和。

哈希表(Hash Map):利用哈希表存储不同前缀和出现的次数。这样,对于每一个新的前缀和,我们可以在常数时间内查询哈希表找到之前有多少个前缀和等于当前前缀和减去k。这是因为如果存在一个旧的前缀和等于当前前缀和减去k,那么从那个旧的前缀到当前前缀的子数组和就为k。

五.代码实现

解法1

cpp 复制代码
class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {

        int result = 0;
        int tmp;
        //0 1 2 0 -1 2 0  3
        int i, j;
        for (vector<int>::iterator it = nums.begin(); it != nums.end(); it++)
        {
            tmp = 0;
            for (vector<int>::iterator itt = it; itt != nums.end(); itt++)
            {
                tmp += *itt;
                if (tmp == k)
                {
                    result++;
                }
            }
        }

        return result;
    }
};

解法2

c 复制代码
class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
        int count = 0, sum = 0;
        unordered_map<int, int> prefixSumCount;
        prefixSumCount[0] = 1;  // 初始化,和为0的前缀和出现一次

        for (int num : nums) {
            sum += num;  // 计算当前前缀和
            // 检查是否存在一个旧的前缀和,使得旧的前缀和与当前前缀和之间的差等于k
            if (prefixSumCount.count(sum - k)) {
                count += prefixSumCount[sum - k];
            }
            // 更新当前前缀和的计数
            prefixSumCount[sum]++;
        }

        return count;
    }
};

六.题目总结

哈希表+前缀和的技术通常用于解决涉及数组或序列累积和的问题,特别是当需要快速查询子数组或子序列和的场合。这种方法特别适用于以下几类问题:

  • 连续子数组的和:最常见的应用是找出数组中和为给定值的连续子数组数量。前缀和可以快速计算任意(i, j]区间的和,而哈希表用来存储各个前缀和出现的次数,从而在O(1)时间内判断是否存在某个特定的前缀和值。
  • 求和等于特定值的子数组数量:如上例所示,通过计算当前前缀和并查询哈希表中是否存在一个或多个前缀和,使得当前前缀和与这些前缀和之差等于目标值,可以快速找到子数组和为特定值的数组数量。
  • 数组的子区间问题:对于求解数组中满足特定条件的子区间(如和为k的子数组)数量问题,可以通过维护一个前缀和的哈希表来优化查找过程,从而避免使用双重循环,实现更高效的算法。
  • 处理多次查询:当面对多次查询数组区间和的问题时,前缀和结合哈希表可以大大减少重复计算,每次查询可以在O(1)时间内完成,特别是当数组不经常变化而查询非常频繁时。
  • 寻找具有特定和的子矩阵:在二维数组(如矩阵)中,前缀和技术可以扩展到二维,用于快速计算任意子矩阵的和,结合哈希表可以用来解决特定和的子矩阵问题。

使用哈希表加前缀和的方法,可以将一些原本时间复杂度较高的问题转化为线性时间复杂度处理,从而大幅提升算法效率。这种方法的关键优势在于它通过空间换时间,利用哈希表来快速访问和更新前缀和信息,避免了冗余的计算和遍历。

相关推荐
逻辑驱动的ken10 分钟前
Java高频面试考点场景题09
java·开发语言·数据库·算法·oracle·哈希算法·散列表
帅小伙―苏25 分钟前
力扣42接雨水
前端·算法·leetcode
AI科技星41 分钟前
精细结构常数α的几何本源:从第一性原理的求导证明、量纲分析与全域验证
算法·机器学习·数学建模·数据挖掘·量子计算
6Hzlia1 小时前
【Hot 100 刷题计划】 LeetCode 287. 寻找重复数 | C++ 数组判环 (快慢指针终极解法)
c++·算法·leetcode
MegaDataFlowers1 小时前
26.删除有序数组中的重复项
算法
码完就睡2 小时前
数据结构——栈和队列的相互模拟
数据结构
iiiiyu2 小时前
常用API(SimpleDateFormat类 & Calendar类 & JDK8日期 时间 日期时间 & JDK8日期(时区) )
java·大数据·开发语言·数据结构·编程语言
故事和你912 小时前
洛谷-数据结构1-4-图的基本应用2
开发语言·数据结构·算法·深度优先·动态规划·图论
吴可可1232 小时前
C#合并首尾相连多段线实战
算法·c#
KMDxiaozuanfeng3 小时前
卡梅德生物技术快报|SPR 技术应用|基于 SPR 亲和力的中药活性成分筛选系统实现与数据分析
科技·算法·面试·考试