leetcode402场周赛——构成整天的下标对数目
原始题目链接:
402场周赛
题目描述
给你一个整数数组 hours
,表示以 小时 为单位的时间,返回一个整数,表示满足 i < j
且 hours[i] + hours[j]
构成 整天 的下标对 i, j
的数目。
整天 定义为时间持续时间是 24 小时的 整数倍 。
例如,1 天是 24 小时,2 天是 48 小时,3 天是 72 小时,以此类推。
示例 1:
输入: hours = [12,12,30,24,24]
输出: 2
解释:
构成整天的下标对分别是 (0, 1) 和 (3, 4)。
示例 2:
输入: hours = [72,48,24,3]
输出: 3
解释:
构成整天的下标对分别是 (0, 1)、(0, 2) 和 (1, 2)。
提示:
1 <= hours.length <= 5 * 105
1 <= hours[i] <= 109
解法一
最简单的解题思路:
- 首先遍历数组中的每一个元素 hours[i] 。
- 对于每个元素,再次遍历后续的元素 hours[j] (其中 j > i )。
- 计算 hours[i] + hours[j] 的和,如果这个和能被 24 整除,说明这两个元素构成整天,计数器加 1 。
function countPairs(hours) {let count = 0; // 用于记录满足条件的下标对数量for (let i = 0; i < hours.length; i++) {for (let j = i + 1; j < hours.length; j++) {if ((hours[i] + hours[j]) % 24 === 0) { // 如果两数之和能被 24 整除count++; // 计数器加 1}}}return count; // 返回满足条件的下标对数量
}let hours1 = [12, 12, 30, 24, 24];
console.log(countPairs(hours1)); // 输出 2let hours2 = [72, 48, 24, 3];
console.log(countPairs(hours2)); // 输出 3
但这样的时间复杂度较高
解法二
解题思路:
- 首先创建一个哈希表 countMap 来存储每个小时数除以 24 的余数出现的次数。
- 遍历数组 hours ,对于每个小时数 hour ,计算其除以 24 的余数 remainder 。
- 计算与 remainder 互补能构成整天的余数 complement (即 24 - remainder ,若 remainder === 0 则 complement = 0 )。
- 在哈希表中查找 complement 的出现次数,如果存在,则将其累加到结果计数器 count 中。
- 同时,更新当前余数 remainder 在哈希表中的出现次数。
function countPairs(hours) {let count = 0; // 用于记录满足条件的下标对数量let countMap = {}; // 存储每个余数出现的次数for (let hour of hours) {let remainder = hour % 24; // 计算余数let complement = remainder === 0? 0 : 24 - remainder; // 计算互补的余数if (countMap[complement]) {count += countMap[complement]; // 累加互补余数的出现次数}if (countMap[remainder]) {countMap[remainder]++;} else {countMap[remainder] = 1;}}return count;
}
本质上,我们通过countMap
这个对象,来存储每个余数出现的次数,从而减少方法一里面的两层遍历,使得只用一次遍历即可。