前缀和题目:连续的子数组和

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 解法
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:连续的子数组和

出处:523. 连续的子数组和

难度

5 级

题目描述

要求

给定一个整数数组 nums \texttt{nums} nums 和一个整数 k \texttt{k} k,如果 nums \texttt{nums} nums 有一个连续子数组满足大小至少为 2 \texttt{2} 2 且元素和是 k \texttt{k} k 的倍数,则返回 true \texttt{true} true,否则返回 false \texttt{false} false

对于整数 x \texttt{x} x,如果存在一个整数 n \texttt{n} n 使得 x = n × k \texttt{x} = \texttt{n} \times \texttt{k} x=n×k,则 x \texttt{x} x k \texttt{k} k 的倍数。 0 \texttt{0} 0 总是 k \texttt{k} k 的倍数。

示例

示例 1:

输入: nums = [23,2,4,6,7], k = 6 \texttt{nums = [23,2,4,6,7], k = 6} nums = [23,2,4,6,7], k = 6
输出: true \texttt{true} true
解释: [2, 4] \texttt{[2, 4]} [2, 4] 是大小为 2 \texttt{2} 2 的子数组,和为 6 \texttt{6} 6

示例 2:

输入: nums = [23,2,6,4,7], k = 6 \texttt{nums = [23,2,6,4,7], k = 6} nums = [23,2,6,4,7], k = 6
输出: true \texttt{true} true
解释: [23, 2, 6, 4, 7] \texttt{[23, 2, 6, 4, 7]} [23, 2, 6, 4, 7] 是大小为 5 \texttt{5} 5 的子数组,和为 42 \texttt{42} 42
42 \texttt{42} 42 6 \texttt{6} 6 的倍数,因为 42 = 7 × 6 \texttt{42} = \texttt{7} \times \texttt{6} 42=7×6 7 \texttt{7} 7 是一个整数。

示例 3:

输入: nums = [23,2,6,4,7], k = 13 \texttt{nums = [23,2,6,4,7], k = 13} nums = [23,2,6,4,7], k = 13
输出: false \texttt{false} false

数据范围

  • 1 ≤ nums.length ≤ 10 5 \texttt{1} \le \texttt{nums.length} \le \texttt{10}^\texttt{5} 1nums.length105
  • 0 ≤ nums[i] ≤ 10 9 \texttt{0} \le \texttt{nums[i]} \le \texttt{10}^\texttt{9} 0nums[i]109
  • 0 ≤ sum(nums[i]) ≤ 2 31 − 1 \texttt{0} \le \texttt{sum(nums[i])} \le \texttt{2}^\texttt{31} - \texttt{1} 0sum(nums[i])2311
  • 1 ≤ k ≤ 2 31 − 1 \texttt{1} \le \texttt{k} \le \texttt{2}^\texttt{31} - \texttt{1} 1k2311

解法

思路和算法

只有当数组 nums \textit{nums} nums 的长度至少为 2 2 2 时,才可能存在长度至少为 2 2 2 的子数组。如果数组 nums \textit{nums} nums 的长度小于 2 2 2,则一定不存在长度至少为 2 2 2 的子数组,返回 false \text{false} false

当数组 nums \textit{nums} nums 的长度至少为 2 2 2 时,为了计算数组 nums \textit{nums} nums 的子数组的元素和,需要计算数组 nums \textit{nums} nums 的前缀和,根据前缀和得到任意一个子数组的元素和。

为了判断子数组的元素和是否为 k k k 的倍数,需要计算前缀和模 k k k 的余数。对于两个不同的下标 i i i j j j,其中 i < j i < j i<j,如果这两个下标对应的前缀和模 k k k 的余数相同,则下标范围 [ i + 1 , j ] [i + 1, j] [i+1,j] 的子数组的元素和为 k k k 的倍数,该子数组的长度为 j − i j - i ji。由于这道题要求子数组的长度至少为 2 2 2,因此应该寻找符合要求的最长子数组,需要记录每个余数的第一次出现的下标。

从左到右遍历数组 nums \textit{nums} nums,遍历过程中计算前缀和模 k k k 的余数,并使用哈希表记录每个余数的首次出现下标。由于空前缀不包含任何元素,前缀和为 0 0 0,余数也为 0 0 0,其下标为 − 1 -1 1,因此首先将余数 0 0 0 对应下标 − 1 -1 1 存入哈希表。

sum \textit{sum} sum 表示前缀和模 k k k 的余数,初始时 sum = 0 \textit{sum} = 0 sum=0。遍历到每个元素时,将该元素值加到 sum \textit{sum} sum,然后将 sum \textit{sum} sum 的值更新为 sum m o d k \textit{sum} \bmod k summodk(应确保 0 ≤ sum < k 0 \le \textit{sum} < k 0sum<k)。更新 sum \textit{sum} sum 的值之后,判断哈希表中是否存在余数 sum \textit{sum} sum,执行相应的操作。

  • 如果哈希表中存在余数 sum \textit{sum} sum,则从哈希表中得到 sum \textit{sum} sum 第一次出现的下标 prevIndex \textit{prevIndex} prevIndex,用 i i i 表示当前下标,则以当前元素结尾的和为 k k k 的倍数的最长子数组的长度是 i − prevIndex i - \textit{prevIndex} iprevIndex,如果 i − prevIndex ≥ 2 i - \textit{prevIndex} \ge 2 iprevIndex2,则找到一个长度至少为 2 2 2 且和为 k k k 的倍数的的子数组,返回 true \text{true} true

  • 如果哈希表中不存在余数 sum \textit{sum} sum,则当前下标是余数 sum \textit{sum} sum 第一次出现,将 sum \textit{sum} sum 对应下标 i i i 存入哈希表。

遍历结束之后,如果没有找到长度至少为 2 2 2 且和为 k k k 的倍数的的子数组,则返回 false \text{false} false

由于哈希表中存储的是每个余数第一次出现的下标,因此当遍历到下标 i i i 时,如果哈希表中存在相同余数的下标 prevIndex \textit{prevIndex} prevIndex,则以下标 i i i 结尾的和为 k k k 的倍数的最长子数组的长度是 i − prevIndex i - \textit{prevIndex} iprevIndex。如果 i − prevIndex < 2 i - \textit{prevIndex} < 2 iprevIndex<2,则以下标 i i i 结尾的子数组中不存在长度至少为 2 2 2 且和为 k k k 的倍数的子数组。因此上述做法可以确保得到正确的结果。

代码

class Solution {public boolean checkSubarraySum(int[] nums, int k) {int length = nums.length;if (length < 2) {return false;}Map<Integer, Integer> indices = new HashMap<Integer, Integer>();indices.put(0, -1);int sum = 0;for (int i = 0; i < length; i++) {sum = (sum + nums[i]) % k;if (indices.containsKey(sum)) {int prevIndex = indices.get(sum);if (i - prevIndex >= 2) {return true;}} else {indices.put(sum, i);}}return false;}
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 nums \textit{nums} nums 的长度。需要遍历数组一次计算前缀和模 k k k 的余数,对于每个元素,更新余数、计算答案与操作哈希表的时间都是 O ( 1 ) O(1) O(1)

  • 空间复杂度: O ( k ) O(k) O(k),其中 k k k 是给定的整数。空间复杂度主要取决于哈希表,哈希表中的不同余数个数不超过 k k k 个。

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

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

相关文章

队的简单介绍

队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出 FIFO(First In First Out)的特点。 入队列&#xff1a;进行插入操作的一端称为队尾。 出队列&#xff1a;进行删除操作的一端称为队头。 入队列…

AI-Sphere-Butler之如何将豆包桌面版对接到AI全能管家~新玩法(一)

环境&#xff1a; AI-Sphere-Butler VBCABLE2.1.58 Win10专业版 豆包桌面版1.47.4 ubuntu22.04 英伟达4070ti 12G python3.10 问题描述&#xff1a; AI-Sphere-Butler之如何将豆包桌面版对接到AI全能管家~新玩法&#xff08;一&#xff09; 聊天视频&#xff1a; AI真…

【STM32】启动流程

1、.s启动文件解析 STM32的启动文件&#xff08;一般是.s汇编文件&#xff0c;如startup_stm32f407xx.s&#xff09;是STM32上电后执行的第一段代码&#xff0c;承担着“系统初始化化引导员”的角色。 它的主要作用是设置初始化栈指针&#xff08;SP&#xff09;、程序计数器&…

【vim】通过vim编辑器打开、修改、退出配置文件

通过vim编辑器打开任一配置文件 vim /etc/profile 英文输入下&#xff0c;按i键进入INSERT模式&#xff0c;修改配置文件 完成修改后&#xff0c;按esc键退出INSERT模式 英文输入下&#xff0c;输入":wq!"&#xff0c;即可保存并退出 :q #不保存并退出 :q! …

Effective Modern C++ 条款6:当 auto 推导类型不符合预期时,使用显式类型初始化惯用法

在C开发中&#xff0c;auto关键字以其简洁性和高效性被广泛使用。然而&#xff0c;“自动推导”并非万能&#xff0c;尤其在某些特殊场景下&#xff0c;auto的推导结果可能与开发者预期不符&#xff0c;甚至导致未定义行为。今天&#xff0c;我们以《Effective Modern C》条款6…

学习Linux进程冻结技术

原文&#xff1a;蜗窝科技Linux进程冻结技术 功耗中经常需要用到&#xff0c;但是linux这块了解甚少&#xff0c;看到这个文章还蛮适合我阅读的 1 什么是进程冻结 进程冻结技术&#xff08;freezing of tasks&#xff09;是指在系统hibernate或者suspend的时候&#xff0c;将…

GitHub 趋势日报 (2025年06月22日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 624 LLMs-from-scratch 523 ai-engineering-hub 501 n8n 320 data-engineer-handb…

kotlin中为什么新增扩展函数功能?

在 Kotlin 中&#xff0c;扩展函数的本质是「不修改原有类代码&#xff0c;为其新增功能」&#xff0c;这源自编程中「开闭原则」&#xff08;对扩展开放&#xff0c;对修改关闭&#xff09;的第一性原理。 核心需求&#xff1a;当需要给第三方库的类&#xff08;如 Android 的…

excel 数据透视表介绍

Excel 数据透视表(PivotTable)就是你的数据分析神器!它能帮你快速汇总、分类、比较和分析 大量数据&#xff0c;从看似杂乱无章的表格中一键提取关键信息 &#xff0c;生成交互式的汇总报告。无需复杂公式&#xff0c;只需拖拽几下&#xff0c;就能让数据“开口说话”&#xff…

半导体行业中的专用标准产品ASSP是什么?

半导体行业中的专用标准产品ASSP是什么&#xff1f; “专用标准产品”&#xff08;ASSP - Application Specific Standard Product&#xff09;是半导体集成电路中的一个重要分类。 你可以把它理解为介于通用标准产品和全定制ASIC之间的一种芯片。以下是它的核心定义和特点&a…

秋招Day14 - MySQL - 锁

MySQL中有几种类型的锁&#xff1f; 锁粒度来分&#xff0c;有表锁、页锁和行锁。 加锁机制划分&#xff0c;有乐观锁和悲观锁。 按兼容性划分&#xff0c;有共享锁和排他锁。 按锁模式划分&#xff0c;有记录锁&#xff0c;间隙锁&#xff0c;next-key锁&#xff0c;意向锁…

/var/lib/docker/overlay2目录过大怎么办

/var/lib/docker/overlay2 是 Docker 默认用于存储 容器镜像和容器运行时数据 的核心目录&#xff0c;基于 overlay2 存储驱动实现。以下是其具体作用和内容的详细解析&#xff1a; 1. overlay2 目录的作用 存储镜像分层结构&#xff1a; Docker 镜像采用分层设计&#xff0c;o…

JimuReport:一款免费的数据可视化报表工具

JimuReport&#xff08;积木报表&#xff09;是一款免费的企业级数据可视化报表软件&#xff0c;提供拖拽的方式像搭建积木一样完成在线设计&#xff0c;功能涵盖数据报表、打印设计、图表报表、门户设计、大屏设计等。 数据源 JimuReport 支持 30 多种数据源&#xff0c;包括…

Neo4j.5.X社区版创建数据库和切换数据库

在使用Neo4j数据库&#xff08;版本&#xff1a;neo4j-community-5.22.0&#xff09;时&#xff0c;系统自带的“neo4j”和“system”数据库适用于日常的简单学习和练习&#xff0c;但对于新的项目&#xff0c;将项目数据与练习数据混用会带来诸多不便&#xff0c;例如查询效率…

DAY33神经网络

浙大疏锦行 定义了一个简单的神经网络&#xff0c;主要是掌握pytorch框架

拼团系统多层限流架构详解

拼团系统多层限流架构详解 一、整体架构设计理念 多层限流采用"层层设防"思想&#xff0c;通过网关层全局流量控制→服务层接口粒度限流→本地资源隔离→热点参数精准防护的四级防御体系&#xff0c;实现从粗到细的流量治理&#xff0c;确保大促期间系统稳定性。 …

[ctfshow web入门] web92 `==`特性与intval特性

信息收集 和之前的题差不多&#xff0c;这次是使用了不严格相等的&#xff0c;详情看这篇博客&#xff1a; 和 在 PHP 中有何区别&#xff1f;一共包含哪些部分&#xff1f; 首先&#xff0c;不能使$num 4476&#xff0c;然后需要使intval($num,0)4476 include("flag…

在Springboot项目部署时遇到,centos服务器上,curl请求目标地址不通 ,curl -x 可以请求通的解决办法

在甲方服务器部署项目时&#xff0c;通常遇到需要开通外网权限的问题&#xff0c;有的是直接给开通服务器的白名单&#xff0c;就可以直接访问白名单外网地址了。也有的是通过网络转发&#xff0c;将url前面的部分替换&#xff0c;可以进行网络请求。有一次遇到一个罕见的&…

Python异步爬虫编程技巧:从入门到高级实战指南

Python异步爬虫编程技巧&#xff1a;从入门到高级实战指南 &#x1f680; &#x1f4da; 目录 前言&#xff1a;为什么要学异步爬虫异步编程基础概念异步爬虫核心技术栈入门实战&#xff1a;第一个异步爬虫进阶技巧&#xff1a;并发控制与资源管理高级实战&#xff1a;分布式…

JMeter-SSE响应数据自动化3.0

背景 此次因为多了一些需要过滤排除的错误(数量很少)&#xff0c;还需要修改下JMeter的jtl文件输出数据&#xff08;后续统计数据需要&#xff09; 所以只涉及到JSR脚本的一些改动(此部分改动并不会影响到JMeter的HTML报告) 改动 主要通过设置JMeter中prev输出数据变量threadN…