刷爆力扣之检查数组对是否可以被 k 整除

简介: 刷爆力扣之检查数组对是否可以被 k 整除

刷爆力扣之检查数组对是否可以被 k 整除

HELLO,各位看官大大好啊,我是阿呆 🙈🙈🙈

今天开始阿呆将会记录下力扣刷题过程,收录在专栏算法中 😜😜😜




该专栏按照不同类别标签进行刷题,每个标签又分为 Easy、Medium、Hard 三个等级 🥳🥳🥳


本部分所有题目均来自于LeetCode 网,并于每道题目下标明具体力扣网原题链接 🏃🏃🏃


OK,兄弟们,废话不多直接上题,冲冲冲 🌞🌞🌞



一 🏠 题目描述

1497. 检查数组对是否可以被 k 整除


给你一个整数数组 arr 和一个整数 k ,其中数组长度是偶数,值为 n


现在需要把数组恰好分成 n / 2 对,以使每对数字的和都能够被 k 整除


如果存在这样的分法,请返回 True ;否则,返回 False


示例 1:


输入:arr = [1,2,3,4,5,10,6,7,8,9], k =5输出:true
解释:划分后的数字对为 (1,9),(2,8),(3,7),(4,6) 以及 (5,10) 

示例 2:


输入:arr = [1,2,3,4,5,6], k =7输出:true
解释:划分后的数字对为 (1,6),(2,5) 以及 (3,4)

示例 3:


输入:arr = [1,2,3,4,5,6], k =10输出:false
解释:无法在将数组中的数字分为三对的同时满足每对数字和能够被 10 整除的条件

提示:


arr.length == n
1 <= n <=105n 为偶数
-109 <= arr[i] <=1091 <= k <=10



二 🏠破题思路

2.1 🚀 关键信息

解决问题第一步,当然先提取题目字面上的关键信息 😎😎😎


把数组恰好分成 n / 2 对 = 即把数组中的元素两两一对进行分组


每对数字和能被 k 整除 = 每组的元素之 sum 对 k 取模结果都为 0 (sum % k = 0)



提取完题目中的关键信息后,直接进入第二阶段,思路整理 😃😃😃


2.2 🚀 思路整理

如果两个数之和能被 k 整除,那这两个数对 k 取模的结果之和也能被 k 整除,这是这道算法题的核心点


那么对于任意的一个数,对 k 取模后记为 Xk,分为以下两种情况


1、若 Xk1 = 0,需找到另一个满足 Xk2 = 0 的数进行配对


2、若 Xk1 > 0,需找到另一个满足 Xk1 + Xk2 = k 的数进行配对



于是可以很容易联想到使用哈希表记录取模结果。对于哈希表的 KEY 表示一个数的余数,VAL 表示这个余数出现的次数。统计完成后,将所有条目进行配对,确保如下两条


1、哈希映射中键 0 对应的值为偶数,对应如上第一种情况


2、哈希映射中键 t (t>0) 和键 k - t 对应的值相等,对应如上第二种情况



小细节


在 C++ 中,将负数 x 对一个正数 k 进行取模操作,得到的结果小于等于 0,即在 [−k+1,0] 范围内 。我们可以通过:xk = (x % k + k) % k ,得到在 [0, k-1] 的范围内的余数 👀👀👀


由于哈希映射中的键的范围为 [0, k-1],因此我们可以使用一个长度为 k 的数组代替哈希表,降低编码难度


整理完解题思路后,直接进入第三阶段,代码实现 😃😃😃



三 🏠 代码详解

3.1 🚀 代码实现

按照我们刚才的破题思路,直接代码走起来 👇👇👇👇


bool canArrange(std::vector<int>& arr, int k) {
    std::vector<int> mod(k); //定义取模数组代替哈希表 ,对应小细节 ②
for (int num: arr) { //遍历输入数组 arr
++mod[(num % k + k) % k]; //对输入数组元素进行取模操作,并对其进行计数
    }
for (int i =1; i + i < k; ++i) { //遍历取模数组
if (mod[i] != mod[k - i]) return false; //若不满足第二种配对情况直接 return
    }
    return mod[0] % 2==0; //校验是否满足第一种配对情况
}
++mod[(num % k + k) % k]; //对输入数组元素进行取模操作,并对其进行计数

3.2 🚀 细节解析

看完 👀👀👀 全注释版的代码实现后,相信看官大大对整体逻辑已经是大写的 OK 了 😃😃😃


那么我们挖掘上述实现的晦涩细节 😖😖😖 进行解析,直接开干,走起来 👇👇👇👇


++mod[(num % k + k) % k]; //对输入数组元素进行取模操作,并对其进行计数

首先是 (num % k + k) % k ,它对应着小细节 ①,我们这里举出一个例子解释, 例 x = - 1, k = 5


注:以下 y,z 范围为 ( - k,k ),参考 2.2 思路整理


如果满足 (x + y) % k = 0,易得 y = 1


那么 1 对应的正整数满足表达式(1 + z ) % = 0 ,易得 z = 4


因此我们可以得对于数字 y = 1 , x = - 1 和 z = 4 对于(x + y) % k = 0 表达式完全等效


其次是 ++mod[N],这实际就是利用了数组下标作为哈希表的 KEY ,索引值作为哈希表 VAL 在计数而言



i + i < k //遍历取模数组

遍历取模数组的循环条件是否可以写成 i < k ?


当然可以,但是实际上这仅需遍历一半足矣,因为是在拿元素值进行配对比较嘛,这样的效率高 😜😜😜


遍历取模数组的循环条件是否可以写成 i < k / 2 ?


不可以,因为 i 为整型 i + i < k 和 i < k / 2 并不等效,例如 i = 1,k = 3 ,前者表表达式结果为 TRUE ,后者表达式结果为 FALSE 😖😖😖



四 🏠 心路历程

为方便各位看官大大了解博主真实刷题过程,我把当时状态纯纯真实还原,记录在心路历程这一小节,不感兴趣的小伙伴可以直接跳过哈


博主在第一阶段提取 🚀 关键信息并没有问题,在第二阶段 🚀 思路整理中只想到了对任意元素,对 k 取模后可以简化配对过程,但是并没有联想到两种配对情况 😭😭😭 (破题关键点)


所以博主的这道题也是在阅读完官方解析后,解出来并加以记录的


相关文章
|
2月前
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
41 0
|
4月前
|
算法
LeetCode第53题最大子数组和
LeetCode第53题"最大子数组和"的解题方法,利用动态规划思想,通过一次遍历数组,维护到当前元素为止的最大子数组和,有效避免了复杂度更高的暴力解法。
LeetCode第53题最大子数组和
|
4月前
|
存储 Java API
LeetCode------合并两个有序数组(4)【数组】
这篇文章介绍了LeetCode上的"合并两个有序数组"问题,并提供了三种解法:第一种是使用Java的Arrays.sort()方法直接对合并后的数组进行排序;第二种是使用辅助数组和双指针技术进行合并;第三种则是从后向前的双指针方法,避免了使用额外的辅助数组。
LeetCode------合并两个有序数组(4)【数组】
|
4月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
123 2
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 03. 数组中重复的数字
解决剑指Offer题目 "数组中重复的数字" 的Python实现方法,通过使用字典来记录数组中每个数字的出现次数,快速找出重复的数字。
39 1
LeetCode------找到所有数组中消失的数字(6)【数组】
这篇文章介绍了LeetCode上的"找到所有数组中消失的数字"问题,提供了一种解法,通过两次遍历来找出所有未在数组中出现的数字:第一次遍历将数组中的每个数字对应位置的值增加数组长度,第二次遍历找出所有未被增加的数字,即缺失的数字。
|
4月前
|
前端开发
LeetCode------移动零(5)【数组】
这篇文章介绍了LeetCode上的"移动零"问题,提出了一种使用双指针的原地操作解法,该方法首先将非零元素移动到数组前端并保持相对顺序,然后填充后续位置为零,以达到题目要求。
|
2月前
【LeetCode-每日一题】 删除排序数组中的重复项
【LeetCode-每日一题】 删除排序数组中的重复项
21 4
|
2月前
|
索引
Leetcode第三十三题(搜索旋转排序数组)
这篇文章介绍了解决LeetCode第33题“搜索旋转排序数组”的方法,该问题要求在旋转过的升序数组中找到给定目标值的索引,如果存在则返回索引,否则返回-1,文章提供了一个时间复杂度为O(logn)的二分搜索算法实现。
22 0
Leetcode第三十三题(搜索旋转排序数组)
|
2月前
|
算法 C++
Leetcode第53题(最大子数组和)
这篇文章介绍了LeetCode第53题“最大子数组和”的动态规划解法,提供了详细的状态转移方程和C++代码实现,并讨论了其他算法如贪心、分治、改进动态规划和分块累计法。
69 0