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

滑动窗口不能处理负数

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

但当数组中包含负数时

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

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

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

如果 从某个位置i ,到当前位置 j 的和为 k,(子数组 nums[i: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
相关推荐
独自破碎E3 小时前
【队列】按之字形顺序打印二叉树
leetcode
AlenTech3 小时前
206. 反转链表 - 力扣(LeetCode)
数据结构·leetcode·链表
踩坑记录3 小时前
leetcode hot100 438. 找到字符串中所有字母异位词 滑动窗口 medium
leetcode·职场和发展
YuTaoShao4 小时前
【LeetCode 每日一题】1458. 两个子序列的最大点积——(解法三)状态压缩
算法·leetcode·职场和发展
橘颂TA4 小时前
【剑斩OFFER】算法的暴力美学——leetCode 946 题:验证栈序列
c++·算法·leetcode·职场和发展·结构与算法
wen__xvn4 小时前
力扣第 484 场周赛
算法·leetcode·职场和发展
YuTaoShao4 小时前
【LeetCode 每日一题】865. 具有所有最深节点的最小子树——(解法一)自顶向下
算法·leetcode·职场和发展
独自破碎E5 小时前
【队列】求二叉树的层序遍历
leetcode
Tisfy5 小时前
LeetCode 0085.最大矩形:单调栈
算法·leetcode·题解·单调栈