力扣每日打卡 3185.构成整天的下标对数目 II

60 阅读2分钟

前言

这是刷算法题的第二天,所以会很生疏,用到的语言是JS 题目:力扣 3185.构成整天的下标对数目 II 这道题与 力扣 3184. 构成整天的下标对数目 I 简直有异曲同工之妙,区别就是数字的范围


一、题目内容

给你一个整数数组 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 * 10^5^
1 <= hours[i] <= 10^9^

二、解题方法

1.使用哈希表

代码如下(示例):

/**
 * @param {number[]} hours
 * @return {number}
 */
var countCompleteDayPairs = function(hours) {
    const hash = {}
    let count = 0
    for( const item of hours ) {
      const rem = item % 24 // 第一个余数
      const comp =  (24 - rem) % 24 // 第二个余数
      count = count + (hash[comp] || 0) // 若存在有第二个余数,则将第二个余数的个数累加到count
      hash[rem] = (hash[rem] || 0) + 1 // 将循环过的数字推进到hash表里   
    }
    return count
}

2.官方解题

思路与算法

hours[i]+hours[j] 能够被 24 整除,只需 hours[i] 除以 24 的余数与 hours[j] 除以 24 的余数之和能够被 24 整除。

我们可以枚举 hours[i],每一个 hours[i] 对答案的贡献就是能与其成对的 hours[j] 的数量。如果暴力查找能够成对的 hours[j],则每次都需要遍历一遍 hours 数组中剩余的元素。我们可以使用一个长度为 24 的数组 cnt 记录每个余数的出现次数,从而快速查询能够与 hours[i] 成对的元素数量。

注意,哈希表记录的是位于我们当前枚举的 hours[i] 左边的元素,也就是说我们是在枚举右边值的同时维护左边的元素。

代码如下(示例):


JavaScript
var countCompleteDayPairs = function(hours) {
    let ans = 0;
    let cnt = new Array(24).fill(0);
    for (let hour of hours) {
        ans += cnt[(24 - hour % 24) % 24];
        cnt[hour % 24]++;
    }
    return ans;
};


链接:力扣本题官方题解
来源:力扣(LeetCode)