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
相关推荐
LuminousCPP2 小时前
栈和队列专题(四):LeetCode 232. 用栈实现队列|双栈分工 + 按需迁移 + 摊还 O(1)
c语言·数据结构·笔记·算法·leetcode
青 春 记 忆2 小时前
LeetCode 155. 最小栈|Python 解法详解
开发语言·python·leetcode
鹿角片ljp11 小时前
LeetCode 46. 全排列|吃透回溯
算法·leetcode·职场和发展
.道阻且长.13 小时前
11.LeetCode算法习题讲解--滑动窗口--将x减到0的最小操作数
算法·leetcode·职场和发展
wenyq714 小时前
LeetCode 2460. Apply Operations to an Array
算法·leetcode
青 春 记 忆15 小时前
LeetCode 142. 环形链表 II|Python 解法详解
python·leetcode·链表
小欣加油15 小时前
leetcode3069 将元素分配到两个数组中I
数据结构·c++·算法·leetcode·职场和发展
从琳开始98920 小时前
优选算法——双指针(算法原理+力扣题)
算法·leetcode·职场和发展
从琳开始98920 小时前
优选算法——滑动窗口(概念+解题模板+LeetCode例题讲解)
算法·leetcode·职场和发展
Nil20820 小时前
leetcode 94二叉树的中序遍历
算法·leetcode·职场和发展