【刷题打卡】1010. 总持续时间可被 60 整除的歌曲

133 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一、题目描述:

1010. 总持续时间可被 60 整除的歌曲 - 力扣(LeetCode) (leetcode-cn.com)

在歌曲列表中,第 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 * 10^4
  • 1 <= time[i] <= 500

二、思路分析:

题中形式上,希望索引的数字 i 和 j 满足 i < j 且有 (time[i] + time[j]) % 60 == 0。

所以我们可以变换着思考解题,由于要求可以被60整除,可以把数字变换一下再进行计算

如下:

[30,20,150,100,40] = [30,20,30,40,40],余上60后,我们就比较容易进行查找了。

这里没有按顺序查找,而是使用类似hash表的形式;如下:

  1. 首先统计每个数字的个数,20->1个,30->2个,40->2个;
  2. 依次匹配就可以了,对于20我们找40,对于30我们找30;需要注意,题中要求从左向右(i<j),所以当30=30时,我们对数的累加为1+2+3+...+cnt-1;其它的则为cnt1*cnt2;

三、AC 代码:

#define MAXS 60
int numPairsDivisibleBy60(int* time, int timeSize) {
    int pTime[MAXS] = { 0 };
    int i = 0;
    while (i < timeSize) {
        time[i] = time[i] % 60;
        pTime[time[i]]++;
        i++;
    }
    int resCnt;
    i = resCnt = 0;
    int visit[MAXS] = { 0 };
    while (i < MAXS) {
        if (pTime[i] != 0 && visit[i] == 0) {
            int base = i;
            int res = (60 - base) % 60;
            if (pTime[res] != 0) {
                if (res == base) {
                    for (int j = 1; j < pTime[base]; j++) {
                        resCnt += j;
                    }
                } else {
                    resCnt += pTime[base] * pTime[res];
                }
                visit[res] = 1;
            }
            visit[i] = 1;
        }
        i++;
    }
    return resCnt;
}

范文参考:

1010. c++几乎双百的哈希解法 - 总持续时间可被 60 整除的歌曲 - 力扣(LeetCode) (leetcode-cn.com)