当前位置: 首页 > news >正文

【LeetCode刷题】和为K的子数组

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

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

示例 1:

输入:nums = [1,1,1], k = 2
输出:2

示例 2:

输入:nums = [1,2,3], k = 3
输出:2

提示:

  • 1 <= nums.length <= 2 * 10^4
  • -1000 <= nums[i] <= 1000
  • -107 <= k <= 10^7

解题思路:

1. 用前缀和表示子数组和

定义前缀和 pre_sum 为数组前 i 个元素的累计和(即 pre_sum[i] = nums[0] + nums[1] + ... + nums[i-1])。对于任意子数组 nums[j..i](从索引 j 到 i 的连续元素,0 ≤ j ≤ i < n),其和可表示为:子数组和 = pre_sum[i+1] - pre_sum[j]

若该子数组和等于 k,则有:pre_sum[i+1] - pre_sum[j] = k → pre_sum[j] = pre_sum[i+1] - k

因此,问题转化为:对于每个前缀和 pre_sum[i],统计有多少个之前的前缀和 pre_sum[j] 等于 pre_sum[i] - k,这些 j 对应的子数组 nums[j..i-1] 的和即为 k

2.记录前缀和出现次数

为了快速统计 “等于 pre_sum[i] - k 的前缀和” 的个数,使用哈希表 hash_map 存储前缀和的值该值出现的次数的映射。

  • 初始状态hash_map[0] = 1这是为了处理 “子数组从索引 0 开始” 的特殊情况。例如,若 pre_sum[i] = k,则 pre_sum[i] - k = 0,此时需要统计到初始的 pre_sum=0(对应 j=0)。

  • 遍历过程:遍历数组时,不断更新当前前缀和 pre_sum,并检查 pre_sum - k 是否在哈希表中:

    • 若存在,说明有 hash_map[pre_sum - k] 个符合条件的子数组,将其累加到结果 count 中;
    • 然后将当前前缀和 pre_sum 存入哈希表(次数加 1),供后续遍历使用。

时间与空间复杂度分析:

  • 时间复杂度O(n)n 为数组长度)。仅需遍历数组一次,哈希表的插入和查询操作均为 O(1)
  • 空间复杂度O(n)。哈希表最多存储 n 个不同的前缀和(极端情况下所有前缀和均不重复)。

示例说明(以 nums = [1,1,1], k = 2 为例):

  • 初始:pre_sum = 0hash_map = {0:1}count = 0
  • 遍历第 1 个元素 1pre_sum = 0 + 1 = 1pre_sum - k = -1(不在哈希表),count 不变。更新哈希表:hash_map[1] = 1
  • 遍历第 2 个元素 1pre_sum = 1 + 1 = 2pre_sum - k = 0(在哈希表,次数 1),count += 1(此时 count=1)。更新哈希表:hash_map[2] = 1
  • 遍历第 3 个元素 1pre_sum = 2 + 1 = 3pre_sum - k = 1(在哈希表,次数 1),count += 1(此时 count=2)。更新哈希表:hash_map[3] = 1
  • 最终返回 count=2,符合示例结果。

Python代码:

from typing import List
from collections import defaultdictclass Solution:def subarraySum(self, nums: List[int], k: int) -> int:pre_sum = 0count = 0# 哈希表记录前缀和及其出现次数,初始前缀和0出现1次hash_map = defaultdict(int)hash_map[0] = 1for num in nums:pre_sum += num# 若pre_sum - k存在于哈希表,说明存在子数组和为kif pre_sum - k in hash_map:count += hash_map[pre_sum - k]# 更新当前前缀和的出现次数hash_map[pre_sum] += 1return countif __name__ == "__main__":# 处理输入(格式如:nums = [1,1,1], k = 2)import renums_input = input().strip()k_input = input().strip()nums = list(map(int, re.search(r'\[.*?\]', nums_input).group().strip('[]').split(',')))k = int(re.search(r'\d+', k_input).group())solution = Solution()result = solution.subarraySum(nums, k)print(result)

LeetCode提交代码:

class Solution:from typing import Listfrom collections import defaultdictdef subarraySum(self, nums: List[int], k: int) -> int:pre_sum = 0count = 0# 哈希表记录前缀和及其出现次数,初始前缀和0出现1次hash_map = defaultdict(int)hash_map[0] = 1for num in nums:pre_sum += num# 若pre_sum - k存在于哈希表,说明存在子数组和为kif pre_sum - k in hash_map:count += hash_map[pre_sum - k]# 更新当前前缀和的出现次数hash_map[pre_sum] += 1return count

程序运行结果如下:

总结

本文介绍了如何统计数组中连续子数组和等于给定整数k的个数。通过使用前缀和与哈希表技术,将问题转化为查找满足pre_sum[j] = pre_sum[i]-k的前缀和出现次数。算法时间复杂度O(n),空间复杂度O(n)。示例演示了该方法的计算过程,并提供了Python实现代码,可处理输入格式如nums=[1,1,1],k=2的情况。这种方法高效地解决了子数组和统计问题。

http://www.dtcms.com/a/614149.html

相关文章:

  • 网站建设教程免费下载电脑平面设计软件
  • BuildingAI 二开 平台配置菜单和页面功能PRD
  • OFDM、IQ调制与AxC技术介绍
  • Linux快速安装java运行环境
  • div嵌套影响网站收录wordpress后台模版
  • 【工具】BatteryInfoView
  • RGB 颜色值与十六进制颜色码相互转换工具
  • 芜湖市网站开发直播app开发一个需要多少钱
  • 数据类型与变量
  • 如何利用LangChain1.0快速进行天气查询
  • 百度网站公司信息推广怎么做做网站很累
  • 51的DSP来了, 100MHz, STC32G144K246
  • SQL索引失效场景全汇总
  • 启闭机闸门的网站建设上海网站建设 劲晟
  • Windows系统监控利器Sysmon:从安装配置到实战攻防
  • 论文笔记(一百)GEN-0 / Embodied Foundation Models That Scale with Physical Interaction
  • 响应式设计进阶:不同屏幕尺寸下的交互优化方案
  • 指针与一维数组
  • 分销网站建设邯郸服务
  • 前端性能优化指标,最大内容绘制
  • wordpress路由插件开发搜索排名优化
  • Kotlin协程Flow任务流buffer缓冲批量任务,筛选批量中最高优先级任务运行(2)
  • 口碑营销的作用成都抖音seo
  • 12.3 合规保障:GDPR与中国法规的落地实践
  • 怡清源企业网站建设可行性分析最牛餐饮营销手段
  • 门户网站设计要点怎样优化网络速度
  • 《Unity游戏多平台上架风险管控:预研适配与全流程实战指南》
  • 跨域问题解决方案汇总
  • 30-ESP32-S3开发
  • C语言编译爱心 | 深入浅出解析C语言编译过程及技巧