力扣——1010. 总持续时间可被 60 整除的歌曲

234 阅读1分钟

力扣——1010. 总持续时间可被 60 整除的歌曲

1010. 总持续时间可被 60 整除的歌曲

在歌曲列表中,第 i 首歌曲的持续时间为 time[i] 秒。

返回其总持续时间(以秒为单位)可被 60 整除的歌曲对的数量。形式上,我们希望下标数字 ij 满足 i < j 且有 (time[i] + time[j]) % 60 == 0

示例 1:

输入:time = [30,20,150,100,40]
输出:3
解释:这三对的总持续时间可被 60 整除:
(time[0] = 30, time[2] = 150): 总持续时间 180
(time[1] = 20, time[3] = 100): 总持续时间 120
(time[1] = 20, time[4] = 40): 总持续时间 60

示例 2:

输入:time = [60,60,60]
输出:3
解释:所有三对的总持续时间都是 120,可以被 60 整除。

提示:

  • 1 <= time.length <= 6 * 104
  • 1 <= time[i] <= 500

问题解析

做法类似两数之和的哈希表做法。

可以用哈希表记录每个元素的出现次数。

然后我们再次遍历数组,对于每一个数,我们枚举60的倍数,看哈希表内有多少数能和他组成这个60的倍数。比如110,能和10、70组成60的倍数,那就看10和70的出现次数就可以。

然后把所有结果相加。

要注意的地方:

为了防止重复计数,我们只看比当前元素小的其它元素。也就是说我们枚举60的倍数j,则j-time[i]要小于time[i]。比如110虽然也能和130组合成60的倍数,但我们只要小于110的,也就是只计算10和70的出现次数

也是为了防止重复计数,当出现j-time[i]=time[i]的情况时,我们从哈希表内取数的方式要改变。

或者为了方便,直接对数组排序,再一边枚举60的倍数,一边记录元素的出现次数。

AC代码

class Solution {
public:
    int numPairsDivisibleBy60(vector<int>& time) {
        unordered_map<int,int>mymap;
        sort(time.begin(),time.end());
        int ans=0;
        for(auto&i:time)
        {
            
            for(int j=60;j<=1000;j+=60)
            {
                if(j-i>i)break;
                ans+=mymap[j-i];
            }
            mymap[i]++;
        }
        return ans;
    }
};