leetcode402场周赛——构成整天的下标对数目(javascript)

76 阅读2分钟

leetcode402场周赛——构成整天的下标对数目

原始题目链接: 402场周赛

题目描述

给你一个整数数组 hours,表示以 小时 为单位的时间,返回一个整数,表示满足 i < jhours[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 * 10^5

1 <= hours[i] <= 10^9

解法一

最简单的解题思路

  1. 首先遍历数组中的每一个元素 hours[i] 。
  2. 对于每个元素,再次遍历后续的元素 hours[j] (其中 j > i )。
  3. 计算 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));  // 输出 2

let hours2 = [72, 48, 24, 3];
console.log(countPairs(hours2));  // 输出 3

但这样的时间复杂度较高

解法二

解题思路:

  1. 首先创建一个哈希表 countMap 来存储每个小时数除以 24 的余数出现的次数。
  2. 遍历数组 hours ,对于每个小时数 hour ,计算其除以 24 的余数 remainder 。
  3. 计算与 remainder 互补能构成整天的余数 complement (即 24 - remainder ,若 remainder === 0 则 complement = 0 )。
  4. 在哈希表中查找 complement 的出现次数,如果存在,则将其累加到结果计数器 count 中。
  5. 同时,更新当前余数 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这个对象,来存储每个余数出现的次数,从而减少方法一里面的两层遍历,使得只用一次遍历即可。