【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)时间内完成,特别是当数组不经常变化而查询非常频繁时。
  • 寻找具有特定和的子矩阵:在二维数组(如矩阵)中,前缀和技术可以扩展到二维,用于快速计算任意子矩阵的和,结合哈希表可以用来解决特定和的子矩阵问题。

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

相关推荐
无限进步_14 分钟前
【C++】大数相加算法详解:从字符串加法到内存布局的思考
开发语言·c++·windows·git·算法·github·visual studio
C+-C资深大佬31 分钟前
C++ 数据类型转换是如何实现的?
开发语言·c++·算法
cwplh34 分钟前
DP 优化二:斜率优化 DP
算法·动态规划
Hcoco_me1 小时前
大模型面试题90:half2,float4这种优化 与 pack优化的底层原理是什么?
人工智能·算法·机器学习·langchain·vllm
浅念-1 小时前
链表经典面试题目
c语言·数据结构·经验分享·笔记·学习·算法
Python算法实战1 小时前
《大模型面试宝典》(2026版) 正式发布!
人工智能·深度学习·算法·面试·职场和发展·大模型
czwxkn2 小时前
数据结构-线性表
数据结构
tobias.b2 小时前
408真题解析-2010-1-数据结构-栈基础操作
数据结构·408真题解析
菜鸟233号2 小时前
力扣213 打家劫舍II java实现
java·数据结构·算法·leetcode
方便面不加香菜3 小时前
数据结构--栈和队列
c语言·数据结构