leetcode hot100 560.和为 K 的子数组 medium 前缀和 + 哈希表

滑动窗口不能处理负数

滑动窗口的关键假设是:当滑动窗口时,和应该是递增或递减的。

但当数组中包含负数时

增加一个负数可能使得窗口和变得更小,因此不能简单地通过扩大窗口(即增大 right)和收缩窗口(即增大 left)来确保子数组和满足条件

数组有负数------》 前缀和 + 哈希表

从位置0 ,到当前位置的和为 sum

如果 从某个位置i ,到当前位置 j 的和为 k,(子数组 numsi:j 的和为 k)
那么该位置前面的和 为 sum - k :sum(j)−sum(i)=k

⇒sum(i)=sum(j)−k

即,如果 sum - k 在哈希表中, 那么和为k的子数组存在

即

统计有多少子数组和为k ⇒

对每个位置的前缀和 sum,统计前面有多少个前缀和等于 sum - k,就是以当前结尾的满足条件的子数组个数。

python 复制代码
class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
        hash = {0: 1}  # 初始化哈希表,表示前缀和为 0 出现过一次
        sum = 0         # 用来存储当前的前缀和
        count = 0       # 记录和为 k 的子数组的个数
        
        for i in range(len(nums)):  # 遍历每个元素
            sum += nums[i]  # 更新前缀和
            
            # 如果前缀和 sum - k 在哈希表中出现过,  那么从某个位置到当前位置的子数组和为 k
            if (sum - k) in hash:  
                count += hash[sum - k]  #  更新计数
            
            # 如果当前前缀和 sum 在哈希表中出现过,增加其出现次数
            if sum in hash:
                hash[sum] += 1
            else:
                hash[sum] = 1  # 否则将当前前缀和加入哈希表
            
        return count
相关推荐
Tisfy2 小时前
LeetCode 3665.统计镜子反射路径数目:三个动态规划数组
leetcode·动态规划·代理模式·题解
海绵宝宝转agent3 小时前
LeetCode100 二叉树个人题解
算法·leetcode·深度优先
文丑颜不良啊4 小时前
LeetCode1581~1600题目解析
java·leetcode
文丑颜不良啊7 小时前
LeetCode1541~1560题目解析
java·leetcode
文丑颜不良啊17 小时前
LeetCode1481~1500题目解析
java·leetcode
文丑颜不良啊18 小时前
LeetCode1381~1400题目解析
java·leetcode
Tisfy21 小时前
LeetCode 3882.网格图中最小异或路径:动态规划
算法·leetcode·动态规划
A boy CDEF girl1 天前
算法题专栏:优选算法
数据结构·算法·leetcode
驭渊的小故事1 天前
LeetCode 算法题解:滑动窗口与数组合并的实战应用
算法·leetcode·职场和发展
文丑颜不良啊1 天前
LeetCode1501~1520题目解析
java·leetcode