和为K的子数组(LeetCode 560)

文章目录

  • 1.问题描述
  • 2.难度等级
  • 3.热门指数
  • 4.解题思路
    • 方法一:枚举
    • 方法二:前缀和 + 哈希表优化
  • 参考文献

1.问题描述

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

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

示例 1:

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

示例 2:

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

示例 3:

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

提示:

  • 1 <= nums.length <= 2 * 104
  • -1000 <= nums[i] <= 1000
  • -107 <= k <= 107

2.难度等级

Medium。

3.热门指数

★★★★☆

出题公司:阿里、腾讯、字节。

4.解题思路

方法一:枚举

最容易想到是暴力枚举。

考虑以 i 结尾和为 k 的连续子数组个数,我们需要统计符合条件的下标 j 的个数,其中 0≤j≤i 且 [j…i] 这个子数组的和恰好为 k 。

可能有读者会认为假定我们确定了子数组的开头和结尾,还需要 O(n) 的时间复杂度遍历子数组来求和,那样复杂度就将达到 O(n^3) 从而无法通过所有测试用例。但是如果我们知道 [j,i] 子数组的和,就能 O(1) 推出 [j−1,i] 的和,因此这部分的遍历求和是不需要的,我们在枚举下标 j 的时候已经能 O(1) 求出 [j,i] 的子数组之和。

时间复杂度: O(n^2),其中 n 为数组的长度。枚举子数组开头和结尾需要 O(n^2) 的时间,其中求和需要 O(1) 的时间复杂度,因此总时间复杂度为 O(n^2)。

空间复杂度: O(1)。只需要常数空间存放若干变量。

下面以 Golang 为例给出实现。

func subarraySum(nums []int, k int) int {var c intfor i := range nums {var sum intfor j := i; j >= 0 ; j-- {sum += nums[j]if sum == k {c++}}}return c
}

方法二:前缀和 + 哈希表优化

还有更快的算法么?

我们知道方法一的瓶颈在于对每个 i,我们需要枚举所有的 j 来判断是否符合条件。

除了通过加法累加 i 到 j 来判断 [j…i] 这个子数组和是否为 k,我们还可以通过前缀和的减法来判断。

我们定义 pre[i] 为 [0…i] 里所有数的和,则 pre[i] 可以由 pre[i−1] 递推而来,即:

pre[i]=pre[i−1]+nums[i]

那么「[j…i] 这个子数组和为 k 」这个条件我们可以转化为:

pre[i] − pre[j−1] == k

简单移项可得符合条件的下标 j 需要满足:

pre[j-1] == pre[i] - k

所以,当我们考虑以 i 结尾和为 k 的连续子数组个数时,只需要统计有多少个前缀和为 pre[i] - k (即 pre[j - 1])的个数即可。

注意 j <= i,所以 pre[j-1] 表示 i 之前的前缀和。

具体做法如下:

  • 使用 pre 变量记录前缀和,代表 pre[i]。
  • 使用哈希表 hash 记录前缀和出现的次数。键值对为 pre[i] : pre_count。
  • 从左到右遍历数组,计算当前前缀和 pre。
  • 如果 pre - k 在哈希表中,则答案个数累加上 pre[pre - k]。
  • 如果当前 pre 等于 k,则前缀和个数累加 1。
  • 将当前前缀和 pre 记录到哈希表,即 hash[pre] += 1。
  • 最后输出答案个数。

时间复杂度: O(n),其中 n 为数组的长度。我们遍历数组的时间复杂度为 O(n),中间利用哈希表查询删除的复杂度均为 O(1),因此总时间复杂度为 O(n)。

空间复杂度: O(n),其中 n 为数组的长度。哈希表在最坏情况下可能有 n 个不同的键值,因此需要 O(n) 的空间复杂度。

下面以 Golang 为例给出实现。

func subarraySum(nums []int, k int) int {m := make(map[int]int)var preSum intvar c intfor _, v := range nums {preSum += vc += m[preSum-k]if preSum == k {c++}// 将当前前缀和 pre 记录到哈希表。m[preSum]++}return c
}

参考文献

560. 和为K 的子数组

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/226974.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTTP代理服务器脚本录制

1、报错1 target controller is configured to “use recording Controller“ but no such controller exists,ensure_target controller is configured to "use recording -CSDN博客

等等Domino 14.0FP1

大家好&#xff0c;才是真的好。 节奏确实太快了&#xff0c;有时候我深感我也追不上。 以前Notes Domino是三年磨一剑&#xff0c;也就说每三年才发一个大版本&#xff0c;从2019年开始&#xff0c;进行了高频提速&#xff0c;居然一年一个大版本&#xff01; 周末&#xf…

NAT——网络地址转换

目录 一、概念 二、NAT的分类 1.静态NAT 1.1 静态NAT的配置 1.2 利用eNSP小实验加强对静态NAT的理解 2、动态NAT 三、NAPT——端口映射 四、Easy IP 使用一个公网地址可以让所有人都上公网 一、概念 随着Internet的发展和网络应用的增多&#xff0c;IPv4地址枯竭已经成为…

jmeter 如何循环使用接口返回的多值?

有同学在用jmeter做接口测试的时候&#xff0c;经常会遇到这样一种情况&#xff1a; 就是一个接口请求返回了多个值&#xff0c;然后下一个接口想循环使用前一个接口的返回值。 这种要怎么做呢&#xff1f; 有一定基础的人&#xff0c;可能第一反应就是先提取前一个接口返回…

在Node.js中MongoDB排序的方法

本文主要介绍在Node.js中MongoDB排序的方法。 目录 Node.js中MongoDB排序使用原生的mongodb驱动程序进行排序使用Mongoose库中的排序 Node.js中MongoDB排序 在Node.js中使用MongoDB进行排序&#xff0c;可以使用原生的mongodb驱动程序或者Mongoose库。 使用原生的mongodb驱动…

K8s中Service Account和RBAC

一.Service Account详解 1.什么是Service Account&#xff1f; ①.ServiceAccount&#xff08;服务账户&#xff09;是Kubernetes集群中的一种资源对象&#xff0c;用于为Pod或其他资源提供身份验证和授权&#xff0c;以便它们能够与Kubernetes API进行交互。 ②.ServiceAcc…

改进lora-scripts,支持SDXL训练,以及启动脚本

分享下自己改进的一个lora训练脚本&#xff0c;在ubuntu下如果SD-WEBUI的环境已经搭好的话&#xff0c;只需要下载lora-script就可以支持训练了&#xff0c;直接命令行方式训练。 首先&#xff0c;我们需要克隆下项目&#xff1a; git clone https://github.com/Akegarasu/lo…

黑色翻页时钟HTML源码-倒计时单页翻页时钟

黑色翻页时钟HTML源码-倒计时单页翻页时钟这是一个类似fliqlo的黑色翻页时钟HTML源码&#xff0c;它仅包含一个HTML文件&#xff0c;上传到网站后即可使用。该时钟具有查看当前时间、秒表和倒计时功能&#xff0c;并且可以在页面的右下角进行设置。 红色动态炫酷数字时钟html网…

八股文打卡day1——计算机网络(1)

面试题&#xff1a;从输入 URL 到页面展示到底发生了什么&#xff1f; 我的回答&#xff1a; 1.首先在浏览器缓存中寻找该页面资源。如果找到了&#xff0c;就返回页面资源。如果没找到&#xff0c;就进行网络请求。 2.在进行网络请求前&#xff0c;先进行DNS的解析&#xff…

【已解决】在使用poi-tl生成的word文档时候,怎么添加目录?poi-tl生成目录解决办法

需求&#xff1a; 需求的报告模板中大概包括标题、目录、前言、章节&#xff08;根据模板动态生成的标题文字表格图片&#xff09;&#xff0c;其中目录需要根据章节的实际情况动态生成。在网上没有找到什么好的解决方案&#xff0c;请教一下实现思路&#xff0c;非常感谢。 …

PHP的垃圾回收机制是怎样的?

PHP 使用自动垃圾回收机制来管理内存。PHP 的垃圾回收主要依赖于引用计数和周期性垃圾回收两种策略。 引用计数&#xff1a; PHP 使用引用计数来跟踪变量的引用次数。每当一个变量被引用&#xff0c;其引用计数就增加&#xff1b;每当一个引用被释放&#xff0c;计数就减少。当…

工作中 docker 的使用积累

2 进入 openwrt 容器 docker exec -it openwrt /bin/sh3 查看 docker 信息 docker info4 启动容器 4 挂载 overlay mount -t overlay overlay -o lowerdirA:B,upperdirC,workdirworker /tmp/test -t overlay &#xff1a; 指定要挂载的文件系统类型为 overlayoverlay: 指定…

MATLAB 计算两片点云间的最小距离(2种方法) (39)

MATLAB 计算两片点云间的最小距离 (39) 一、算法介绍二、算法实现1.常规计算方法2.基于KD树的快速计算一、算法介绍 假设我们现在有两片点云 1 和 2 ,需要计算二者之间的最小距离,这里提供两种计算方法,分别是常规计算和基于KD树近邻搜索的快速计算方法,使用的测试数据如…

springboot 解析微信小程序获取手机号

引用依赖包 <dependency><groupId>bouncycastle</groupId><artifactId>bcprov-jdk14</artifactId><version>138</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fast…

I2C 从设备

驱动文件 \drivers\i2c\busses\i2c-designware-slave.c I2C控制器 \drivers\i2c\i2c-slave-eeprom.c I2C设备示例 由于作为从&#xff0c;接收主写过来的数据时总是少一个&#xff0c;因为分析相关。 控制器驱动中断 加打印&#xff0c;很多时候不能打印出来。如下中断中…

为什么选择国产WordPress:HelpLook的优势解析

如今网站建设可以说已经是企业必备。而在众多的网站建设工具中&#xff0c;WordPress无疑是其中的佼佼者。作为一款开源的CMS&#xff08;内容管理系统&#xff09;&#xff0c;WordPress拥有丰富的插件和主题&#xff0c;以及强大的功能&#xff0c;使得用户可以轻松地构建出符…

vivado约束方法8

无交互的逻辑互斥时钟组 逻辑排他性时钟是指在不同源点上定义但共享部分的时钟由于多路复用器或其他组合逻辑&#xff0c;它们的时钟树。时间限制向导识别此类时钟&#xff0c;并建议在它们这样做时直接对其进行时钟组约束除了连接到其共享时钟的逻辑之外&#xff0c;彼此之间…

半导体:Gem/Secs基本协议库的开发(5)

此篇是1-4 《半导体》的会和处啦&#xff0c;我们有了协议库&#xff0c;也有了通讯库&#xff0c;这不得快乐的玩一把~ 一、先创建一个从站&#xff0c;也就是我们的Equipment端 QT - guiCONFIG c11 console CONFIG - app_bundle CONFIG no_debug_release # 不会生…

Python 直观理解基尼系数

基尼系数最开始就是衡量人群财富收入是否均衡&#xff0c;大家收入平平&#xff0c;那就是很平均&#xff0c;如果大家收入不平等&#xff0c;那基尼系数就很高。 还是给老干部们讲的言简意赅。 什么是基尼系数 我们接下来直接直观地看吧&#xff0c;程序说话 # -*- coding:…

Chart.js 实现实时动态折线图 并限制最大长度

<!DOCTYPE html> <html><head><title>模拟</title><script src"https://lib.sinaapp.com/js/jquery/3.1.0/jquery-3.1.0.min.js"></script><script src"https://cdn.staticfile.org/Chart.js/3.9.1/chart.js"…