基础数据结构之数组的前缀和技巧:和为K的子数组(LeetCode 560 中等题)

前缀和是一种预处理技巧,通过构建前缀和数组,可以在O(1)时间内计算任意区间的和。

原理

原数组: a₀, a₁, a₂, ..., aₙ

前缀和: prefixi = a₀ + a₁ + ... + aᵢ₋₁

区间和: sum(i, j) = prefixj+1 - prefixi

题目:给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。

子数组是数组中元素的连续非空序列。

解题思路:要子数组求和为k,如果把整个前缀分成两部分,自然想到哈希(小本本),子数组前面的前缀如果跟固定的子数组(和为k)组合起来为当前前缀的总和,那么就说明这个子数组找到了。k值是固定的,只要哈希表中存在差值的记录那么任务就完成了。

遍历整个数组的前缀和,然后减去k看下剩下的前缀和在我们的小本本上吗?如果在,说明我们的子数组已经找到,那就把小本本上的数目加入到总数中;之后不管有没有,我们也要把当前前缀和放到小本本上,为了后来者方便去用。

注意:

1、因为整个数组存在正数、负数、0,不同前缀的值可能是一致的,那就说明我们的差值在哈希表中的时候,其对应的数目也可以是多个,我们的子数组k的起点也就可以是多个,所以加和的时候要加其对应的value,而不是1

2、初始哈希表需预存{0:1}以处理首个元素符合条件的情况

python 复制代码
# 暴力求解(只有部分通过)
class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
        n = len(nums)
        # 子数组个数初始化为0
        result = 0
        for i in range(n):
            # i 直接就满足,那就需要加入计数
            if nums[i] == k:
                result+=1
            # 目标sum = k
            sum = nums[i]
            for j in range(i+1,n):
                sum += nums[j]
                if sum == k:
                    result+=1
                elif sum > k:
                    break
        return result
python 复制代码
# 前缀和+哈希
class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
        # 小本本存前缀和,key是前缀和,value是出现次数
        # 边界条件:注意默认0为1,为了考虑第一个元素就等于k的情况
        prifix_count = {0:1}
        prifix_sum = 0
        count = 0
        n = len(nums)

        for num in nums:
            prifix_sum += num
            # 如果当前(前缀和 - k)的值在哈希表中存在,那就说明我们要的子数组k已经找到,其对应的value值是我们这个子数组k的不同起点的数目,也就是子数组k的数目
            if prifix_sum-k in prifix_count:
                count += prifix_count[prifix_sum-k]

            # 无论是否找到,都要把当前前缀和存到哈希表中,为后来者服务。此前缀和存在则拿到其次数再+1,不在则直接赋值为1
            prifix_count[prifix_sum] = prifix_count.get(prifix_sum,0)+1

        return count
相关推荐
2301_800256111 小时前
数据结构基础期末复习例题
数据结构·算法
变量未定义~2 小时前
单调栈-四元组问题
数据结构·算法
冷小鱼2 小时前
AI Agent 核心算法:任务规划(Planning)的深度技术解析
人工智能·算法·planning
退休倒计时2 小时前
【每日一题】LeetCode 78. 子集 TypeScript
算法·leetcode·typescript
旖-旎2 小时前
《LeetCode 978 最长湍流子数组 || LeetCode 139 单词拆分》
c++·算法·leetcode·动态规划
cxr8282 小时前
第16章 跨域迁移与能力融合——从专家到通才
人工智能·算法·智能体·hermes
学究天人2 小时前
数学公理体系大全:Comprehensive Collection of Mathematical Axiom Systems(补充卷9)
人工智能·线性代数·算法·数学建模·动态规划·原型模式·抽象代数
Keven_112 小时前
算法札记:图的存储方式
算法·图论
斯文的八宝粥2 小时前
SERL:让真机强化学习从“难用”走向“可复现”的强化学习框架 ----(4)算法篇(DrQ vs VICE)
算法
yangdaxiageo3 小时前
算法时代的“心智置顶“:《功夫女足》如何构建GEO正向飞轮
人工智能·科技·算法·aigc