题目描述

给定一个包含非负数的数组和一个目标整数 k,编写一个函数来判断该数组是否含有连续的子数组,其大小至少为 2,总和为 k 的倍数,即总和为 n*k,其中 n 也是一个整数。

示例1

输入:
[23,2,4,6,7], k = 6
输出:
True
解释:
[2,4] 是一个大小为 2 的子数组,并且和为 6。

示例2

输入:
[23,2,6,4,7], k = 6
输出:
True
解释:
[23,2,6,4,7]是大小为 5 的子数组,并且和为 42。

提示

  • 数组的长度不会超过 10000 。
  • 你可以认为所有数字总和在 32 位有符号整数范围内。

题解

暴力法

直接枚举所有的区间,然后求出每个区间的和,看是不是 k 的整数倍就行了。这种方法时间复杂度是

,一定过不了的。

前缀和优化

还是枚举所有区间,但是预处理的时候把所有的前缀和保存到数组里,这样区间求和就可以直接计算出来了。最后时间复杂度是

,理论上应该还是没法通过,但是这题数据太弱,竟然勉强通过了。

求余优化

假设前缀和为 sum ,那么区间 [i, j] 的和就可以表示为 sum[j]-sum[i-1] ,如果它是 k 的倍数,就说明了 sum[j] 和 sum[i-1] 模 k 的余数是相同的。

那么我们就可以提前把 sum 数组里的每个数都对 k 求余,然后看有没有两个余数是相同的,并且距离大于等于 2 就行了。

这只需要用一个哈希表就可以判断一个数有没有在之前出现过了。如果一个数没有出现过,就把它的下标放进哈希表。否则的话就判断当前下标和哈希表中的下标差值,如果大于等于 2 ,就找到合法区间了,直接返回 true 。

代码

c++

class Solution {public:bool checkSubarraySum(vector<int>& nums, int k) {int n = nums.size();if (n < 2) return false;if (!k) {for (int i = 1; i < n; ++i) {if (!nums[i] && !nums[i-1]) {return true;}}return false;}unordered_map<int, int> mp;mp[0] = 0;int sum = 0;for (int i = 0; i < n; ++i) {(sum += nums[i]) %= k;if (mp.find(sum) == mp.end()) {mp[sum] = i + 1;} else if (i + 1 - mp[sum] >= 2) {return true;}}return false;}
};

python

class Solution:def checkSubarraySum(self, nums: List[int], k: int) -> bool:n = len(nums)if k == 0:for i in range(1, n):if nums[i] == 0 and nums[i-1] == 0:return Truereturn Falsemp = {}mp[0] = 0sum = 0for i in range(n):sum += nums[i]sum %= kif sum not in mp:mp[sum] = i + 1elif i + 1 - mp[sum] >= 2:return Truereturn False

后记

c++ 有多种实现方法,可以用 map 、hash_map 、unordered_map 等多种数据结构。其中 hash_map 不在标准库里,这里没法使用。理论上 unordered_map 比 map 会快一点,但是实际运行中没有发现差别。

如何表示数组所有数都不等于一个数_每日算法系列【LeetCode 523】连续的子数组和...相关推荐

  1. 如何表示数组所有数都不等于一个数_每日算法系列【LeetCode 330】按要求补齐数组...

    题目描述 给定一个已排序的正整数数组 nums ,和一个正整数 n .从 [1, n] 区间内选取任意个数字补充到 nums 中,使得 [1, n] 区间内的任何数字都可以用 nums 中某几个数字的 ...

  2. 如何判断数组所有数都不等于一个数_工程师编程,C语言学习,关于数组方面的一些总结...

    在学习编程语言时,无论如何我们都逃不掉关于数组这个问题. 那么,在谈及这个问题时,我会从三个方面来思考: 1.数组的定义是什么,也就是何为数组? 2.如何在数组中填充元素(数据)? 3.如何用数组来解 ...

  3. 如何判断数组所有数都不等于一个数_【每日算法Day 91】求解数组中出现次数超过1/3的那个数

    题目链接 LeetCode 229. 求众数 II[1] 题目描述 给定一个大小为 的数组,找出其中所有出现超过 次的元素. 说明: 要求算法的时间复杂度为 ,空间复杂度为 . 示例1 输入: [3, ...

  4. 如何表示数组所有数都不等于一个数_力扣刷题那些事儿(3)-缺失的第一个正整数(41)...

    问题描述 官网题目地址: 力扣​leetcode-cn.com 问题分析 典型的 "看起来很简单" 的题目,但再仔细看发现要求时间复杂度和空间复杂度要求就知道自己错了. 简单描述就 ...

  5. leetcode —— 523. 连续的子数组和

    给定一个包含非负数的数组和一个目标整数 k,编写一个函数来判断该数组是否含有连续的子数组,其大小至少为 2,总和为 k 的倍数,即总和为 n*k,其中 n 也是一个整数. 示例 1: 输入: [23, ...

  6. leetcode 523. 连续的子数组和

    给你一个整数数组 nums 和一个整数 k ,编写一个函数来判断该数组是否含有同时满足下述条件的连续子数组: 子数组大小 至少为 2 ,且 子数组元素总和为 k 的倍数. 如果存在,返回 true : ...

  7. 文巾解题 523. 连续的子数组和

    1  题目描述 2 解题思路 2.1 前缀和+逐元素遍历 一开始想用前缀和+逐起止坐标来遍历的方法判断有没有符合条件的子数组.(就是先算出a[0], a[0]+a[1], a[0]+a[1]+a[2] ...

  8. LeetCode-笔记-523. 连续的子数组和

    LeetCode-笔记-523. 连续的子数组和 看完525题来看523题 给你一个整数数组 nums 和一个整数 k ,编写一个函数来判断该数组是否含有同时满足下述条件的连续子数组: 子数组大小 至 ...

  9. 数组最大可以开多大_每日算法系列【LeetCode 689】三个无重叠子数组的最大和

    题目描述 给定数组 由正整数组成,找到三个互不重叠的子数组的最大和. 每个子数组的长度为 ,我们要使这 个项的和最大化. 返回每个区间起始索引的列表(索引从 0 开始).如果有多个结果,返回字典序最小 ...

最新文章

  1. JQuery实现点击TreeView文本展开/折叠子节点
  2. legend3---5、lavarel爬坑杂记
  3. Oracle 同义词的创建及其作用
  4. vaadin 10+_Vaadin 10+作为CUBA UI的未来
  5. IT公司刻板印象合集:程序员都秃头,商务个个是人精
  6. Lesson 2 Gradient Desent
  7. Kepware AB驱动 · 秒懂百科
  8. 用C语言实现“电子词典”项目
  9. 色谱计算机常用英文,色谱术语的常用中英文对照
  10. 华三H3C路由器配置FTP服务并使用电脑连接ftp传输文件
  11. 网络同步在游戏历史中的发展变化(二)—— Lockstep与帧同步
  12. 百度小程序坐拥三大亿级流量入口 如何低成本制作百度小程序?
  13. 如何用待办工具组织每周的任务清单
  14. python通过指定网卡发包_Python选择网卡发包及接收数据包
  15. 英华鸿蒙幼儿园一日活动,一日生活常规教研活动——记东升丰乐幼儿园第七次教研活动...
  16. 斗地主洗牌+发牌+排序
  17. Java实现8枚硬币问题(减治法)
  18. 第一个TensorFlow模型:摄氏度转换为华氏度
  19. Flutter MD5加密工具类
  20. 一次弄懂香浓极限的含义(几种信噪比含义探讨)

热门文章

  1. axios 登录后设置header_axios如何利用promise无痛刷新token
  2. 浙大python判断两个字符串是否为变位词_python数据结构与算法 变位词
  3. service 层注入不同的数据源_.NET 理论基础+实战控制台程序实现AutoFac注入
  4. python字符串与文本处理技巧(1):分割、首尾匹配、模式搜索、匹配替换
  5. 3DSlicer3:模块管理(一)颜色、DCM、数据、模型、注释
  6. 3Dslicer1:入门及基本控制
  7. 如何在阅读参考文献时,有效率的做笔记?
  8. 23种设计模式C++源码与UML实现--中介者模式
  9. linux中以A开头的函数使用方式历程及详解
  10. 文件没有图标,无法打开(以pdf为例)