LeetCode算法心得——和可被 K 整除的子数组(前缀和+HashMap)

大家好,我是晴天学长,同余定理的应用,需要的小伙伴可以关注支持一下哦!后续会继续更新的。


1) .和可被 K 整除的子数组

在这里插入图片描述
题目描述

给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续、非空)子数组的数目。

示例:

输入:A = [4,5,0,-2,-3,1], K = 5 输出:7

解释:

有 7 个子数组满足其元素之和可被 K = 5 整除: [4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3]

示例 2:

输入: nums = [5], k = 9
输出: 0


2) .算法思路

前缀和+HashMap

解析:

我们需要求出满足条件的区间,见下图
在这里插入图片描述
我们需要找到满足,和为 K 的区间。我们此时 presum 是已知的,k 也是已知的,我们只需要找到 presum - k区间的个数,就能得到 k 的区间个数。但是我们在当前题目中应该怎么做呢?见下图。

在这里插入图片描述
我们在之前的例子中说到,presum[j+1] - presum[i] 可以得到 nums[i] + nums[i+1]+… nums[j],也就是[i,j]区间的和。

那么我们想要判断区间 [i,j] 的和是否能整除 K,也就是上图中紫色那一段是否能整除 K,那么我们只需判断

(presum[j+1] - presum[i] ) % k 是否等于 0 即可,

我们假设 (presum[j+1] - presum[i] ) % k == 0;则

presum[j+1] % k - presum[i] % k == 0;

presum[j +1] % k = presum[i] % k ;

我们 presum[j +1] % k 的值 key 是已知的,则是当前的 presum 和 k 的关系,我们只需要知道之前的前缀区间里含有相同余数 (key)的个数。则能够知道当前能够整除 K 的区间个数。见下图
在这里插入图片描述
我们看到上面代码中有一段代码是这样的
int key = (presum % K + K) % K;
这是为什么呢?不能直接用 presum % k 吗?

这是因为当我们 presum 为负数时,需要对其纠正。纠正前(-1) %2 = (-1),纠正之后 ( (-1) % 2 + 2) % 2=1 保存在哈希表中的则为 1.则不会漏掉部分情况,例如输入为 [-1,2,9],K = 2如果不对其纠正则会漏掉区间 [2] 此时 2 % 2 = 0,符合条件,但是不会被计数。

那么这个题目我们可不可以用数组,代替 map 呢?当然也是可以的,因为此时我们的哈希表存的是余数,余数最大也只不过是 K-1所以我们可以用固定长度 K 的数组来模拟哈希表。


3) .算法步骤

1.创建一个HashMap对象 map 用于存储余数与对应出现次数的映射关系。
2.初始化变量 PerSum 为0,表示当前位置的前缀和。
3.初始化变量 answer 为0,表示满足条件的子数组个数。
4.将余数为0的初始情况放入 map 中,即前缀和为0的情况,出现次数为1。
5.使用一个循环遍历数组中的元素。
6.将当前元素的值累加到 PerSum 中,即计算当前位置的前缀和。
7.使用同余定理,计算当前前缀和除以k的余数,由于负数取模的结果可能为负数,为8.确保结果为非负整数,需要进行加k再取模的操作。
9.检查 map 中是否包含当前余数,如果是,则将对应的出现次数加到 answer 中。
10.将当前余数和对应的出现次数放入 map 中,更新映射关系。
11.循环结束后,返回 answer,表示满足条件的子数组个数。


4).代码示例

class Solution {public int subarraysDivByK(int[] nums, int k) {Map<Integer, Integer> map = new HashMap<Integer, Integer>();long PerSum = 0;int answer = 0;map.put(0, 1);for (int i = 0; i < nums.length; i++) {PerSum += nums[i];// 同余定理,因为不符合分配律int mod = (int) ((PerSum%k+k)%k);if (map.containsKey(mod)) {answer+=map.get(mod);}map.put(mod, map.getOrDefault(mod, 0) + 1);}return answer;}
}

5).总结

  • 同余定理的运用。

试题链接:

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

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

相关文章

使用k8s helm离线部署spark-operator(私有仓库)

制作镜像 docker pull ghcr.io/googlecloudplatform/spark-operator:v1beta2-1.3.8-3.1.1 docker images docker save ImageID > ./spark.tar将制作的镜像上传到目的机器中&#xff0c;加载镜像 docker load < ./spark.tar打标签其中xxxx.xxx/xx/为私有仓库的地址 doc…

尚硅谷大数据项目《在线教育之实时数仓》笔记001

视频地址&#xff1a;尚硅谷大数据项目《在线教育之实时数仓》_哔哩哔哩_bilibili 目录 P001 P002 P003 P004 P005 P001 以在线教育采集系统和离线数仓为前置基础&#xff0c;分为三个部分讲解&#xff1a;实时数仓架构介绍、数仓模型搭建、Suger可视化大屏展示。 P002 P0…

【动态规划刷题 14】最长递增子序列 摆动序列

673. 最长递增子序列的个数 链接: 673. 最长递增子序列的个数 给定一个未排序的整数数组 nums &#xff0c; 返回最长递增子序列的个数 。 注意 这个数列必须是 严格 递增的。 示例 1: 输入: [1,3,5,4,7] 输出: 2 解释: 有两个最长递增子序列&#xff0c;分别是 [1, 3, 4,…

jd(商品详情)API接口

为了进行电商平台 的API开发&#xff0c;首先我们需要做下面几件事情。 1&#xff09;开发者注册一个账号 2&#xff09;然后为每个jd应用注册一个应用程序键&#xff08;App Key) 。 3&#xff09;下载jdAPI的SDK并掌握基本的API基础知识和调用 4&#xff09;利用SDK接口和…

GIS前端-地图事件编程

GIS前端-地图事件编程 图层操作事件地图状态事件交互事件弹出框事件导出PDF 在地图上的一切操作均要采用地图事件机制来实现&#xff0c;即通过鼠标、键盘等交互&#xff0c;触发地图相关事件&#xff0c;进而调用相关功能接口函数实现相应的GIS功能。在具体的实现过程中&#…

openpnp - 设备电源抗干扰部件的选择

文章目录 openpnp - 设备电源抗干扰部件的选择概述END openpnp - 设备电源抗干扰部件的选择 概述 设备电源部分的干扰主要来自伺服和真空泵. 伺服是设备开机期间, 一直供电, 采用滤波器比较好. 型号为 CW4L2-10A-S(004)或者CW4-10A-S(004) CW4L2-10A-S(004)是二级滤波. CW4-1…

07 目标检测-YOLO的基本原理详解

一、YOLO的背景及分类模型 1、YOLO的背景 上图中是手机中的一个app&#xff0c;在任何场景下(工业场景&#xff0c;生活场景等等)都可以试试这个app和这个算法&#xff0c;这个app中间还有一个button&#xff0c;来调节app使用的模型的大小&#xff0c;更大的模型实时性差但精…

从零基础到精通Flutter开发:一步步打造跨平台应用

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 导言 Flutter是一种流行…

【HTML专栏2】VSCode的使用(新建HTML文件)

本文属于HTML/CSS专栏文章&#xff0c;适合WEB前端开发入门学习&#xff0c;详细介绍HTML/CSS如果使用&#xff0c;如果对你有所帮助请一键三连支持&#xff0c;对博主系列文章感兴趣点击下方专栏了解详细。 博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;HTML/CS…

linux 多重启动grub2详解

https://www.gnu.org/software/grub/manual/grub/grub.pdf

合并单元格中自动填充数字序列的方法详解

我们如何在Excel中将序列号填充到不同大小的合并单元格列表中?我们首先想到的是拖动“自动填充”手柄来填充合并的单元格,但在这种情况下,我们将收到以下警告消息,并且无法填充合并的单元。 有没有一种方法可以在不必手动键入数字的情况下对合并的单元格进行编号? 例如,…

HTML基础标签 CSS选择器 JavaScript基础语法 WebAPI_ 页面设计 HTTP协议

第 1 题&#xff08;简答题&#xff09; 题目名称&#xff1a; 编写博客, 总结 HTML 中的常用标签用法 题目内容&#xff1a; 编写博客, 总结 HTML 中的常用标签用法 第 2 题&#xff08;简答题&#xff09; 题目名称&#xff1a; image 标签的 alt 和 title 属性有什么…