LeetCode 热题 100 560. 和为 K 的子数组

news/2025/2/24 14:19:58

LeetCode 热题 100 | 560. 和为 K 的子数组

大家好,今天我们来解决一道经典的算法题——和为 K 的子数组。这道题在 LeetCode 上被标记为中等难度,要求我们统计数组中所有和为 k 的连续子数组的个数。下面我将详细讲解解题思路,并附上 Python 代码实现。


题目描述

给定一个整数数组 nums 和一个整数 k,统计并返回该数组中和为 k 的子数组的个数。子数组是数组中元素的连续非空序列。

示例:

输入:nums = [1,1,1], k = 2
输出:2
解释:子数组 [1,1] 和 [1,1] 的和为 2。

解题思路

我们需要统计数组中所有和为 k 的连续子数组的个数。直接暴力枚举所有子数组的时间复杂度为 O(n²),对于较大的数组会超时。因此,我们需要一种更高效的方法。

核心思想:前缀和 + 哈希表
  1. 前缀和

    • 定义 prefix_sum 表示从数组开头到当前元素的累加和。
    • 对于任意子数组 nums[i..j],其和可以表示为 prefix_sum[j] - prefix_sum[i-1]
  2. 哈希表优化

    • 使用哈希表记录每个前缀和出现的次数。
    • 遍历数组时,计算当前前缀和 prefix_sum,并检查 prefix_sum - k 是否在哈希表中。如果存在,则说明存在若干个子数组的和为 k

代码实现

from collections import defaultdict

def subarraySum(nums, k):
    # 初始化哈希表,记录前缀和出现的次数
    prefix_count = defaultdict(int)
    prefix_count[0] = 1  # 前缀和为 0 的情况出现一次

    prefix_sum = 0  # 当前前缀和
    count = 0  # 满足条件的子数组个数

    for num in nums:
        prefix_sum += num  # 更新前缀和
        # 如果 prefix_sum - k 在哈希表中,说明存在若干个子数组的和为 k
        if prefix_sum - k in prefix_count:
            count += prefix_count[prefix_sum - k]
        # 更新当前前缀和的出现次数
        prefix_count[prefix_sum] += 1

    return count

代码解析

  1. 初始化哈希表

    • prefix_count 用于记录每个前缀和出现的次数。
    • prefix_count[0] = 1 表示前缀和为 0 的情况出现一次(即空数组)。
  2. 遍历数组

    • 计算当前前缀和 prefix_sum
    • 检查 prefix_sum - k 是否在哈希表中。如果存在,则说明存在若干个子数组的和为 k,累加到 count 中。
    • 更新当前前缀和 prefix_sum 的出现次数。
  3. 返回结果

    • 返回满足条件的子数组个数 count

示例运行

示例 1
nums = [1, 1, 1]
k = 2
print(subarraySum(nums, k))  # 输出: 2

解释

  • 前缀和数组为 [1, 2, 3]
  • 满足条件的子数组为 [1, 1][1, 1]
示例 2
nums = [1, 2, 3]
k = 3
print(subarraySum(nums, k))  # 输出: 2

解释

  • 前缀和数组为 [1, 3, 6]
  • 满足条件的子数组为 [1, 2][3]
示例 3
nums = [1, -1, 1, -1]
k = 0
print(subarraySum(nums, k))  # 输出: 4

解释

  • 前缀和数组为 [1, 0, 1, 0]
  • 满足条件的子数组为 [1, -1], [-1, 1], [1, -1], 和 [1, -1, 1, -1]

复杂度分析

  • 时间复杂度:O(n),其中 n 是数组的长度。我们只需要遍历数组一次。
  • 空间复杂度:O(n),哈希表最多存储 n 个前缀和。

总结

通过使用前缀和和哈希表,我们可以高效地统计数组中所有和为 k 的子数组的个数。这种方法的时间复杂度为 O(n),能够处理较大的输入规模。希望这篇题解对你有帮助!如果还有其他问题,欢迎继续提问!

关注我,获取更多算法题解和编程技巧!


http://www.niftyadmin.cn/n/5864450.html

相关文章

缓存基础解释与缓存友好型编程基础

讨论了如何使用快速核心内存(约32,000个字)作为更大、更慢的核心内存(约1,000,000个字)的从属内存(slave)。 通过这种方式,可以在实际使用案例中设计出接近于更快内存的有效访问时间&#xff08…

Vue 3 + Vite 项目中配置代理解决开发环境中跨域请求问题

在 Vue 3 Vite 项目中,配置代理是解决开发环境中跨域请求问题的常见方法。通过在 Vite 的配置文件中设置代理,可以将前端请求转发到后端服务器,从而避免浏览器的同源策略限制。 1. 创建 Vue 3 Vite 项目 首先,确保你已经安装了…

广东英语十二种应用文模版范文

1. 邀请信(Invitation Letter) 模版 Dear [Recipients Name],I hope this letter finds you well. I am writing to invite you to [Event Name] which will be held on [Date] at [Location]. The event will start at [Time] and we would be deligh…

CSS通过webkit-scrollbar设置滚动条样式

查看::-webkit-scrollbar-*各项关系 以下图为例&#xff0c;可以分别定义滚动条背景、滚动轨道、滚动滑块的样式。 需要先给外部容器设置高度&#xff0c;再设置overflow: auto&#xff0c;最后设置三个webkit属性。 <!DOCTYPE html> <html lang"en">…

[LeetCode力扣hot100]-快速选择和快排

快速选择与快速排序的区别&#xff1a; 快速排序&#xff1a;递归地对数组的左右两部分进行排序。快速选择&#xff1a;只递归处理包含第 k 个元素的那一部分&#xff0c;目标是找到第 k 大的元素&#xff0c;而不是对整个数组排序。 快排 void quickSortHelper(vector<i…

MongoDB#常用语句

创建TTL索引(自动删除过期数据) db.xxx_collection.createIndex({ createTime: 1 }, { expireAfterSeconds: 1 * 24 * 60 * 60 * 1000 }); 查询JavaScript函数(mongosh) db.system.js.find 查询document条数 db.getCollection(‘xxx’).countDocuments({}) 根据_id查询 {‘_id’…

07.Docker 数据管理

Docker 数据管理 Docker 数据管理1. 数据卷(data volume)2. 数据卷容器 Docker 数据管理 Docker 镜像由多个只读层叠加而成&#xff0c;启动容器时&#xff0c;Docker 会加载只读镜像层并在镜像栈顶部添加一个读写层。 如果运行中的容器修改了现有的一个已经存在的文件&#…

CentOS-7-x86_64-Minimal-2009 免费下载与使用教程

一、CentOS-7-x86_64-Minimal-2009 简介 CentOS 7 是一款基于 Red Hat Enterprise Linux (RHEL) 的开源操作系统&#xff0c;Minimal 版本 仅包含基础软件包&#xff0c;适合需要轻量化、高定制的服务器或开发环境。 核心优势&#xff1a; 轻量高效&#xff1a;仅需约 900MB 存…