在歌曲列表中,第 i 首歌曲的持续时间为 time[i] 秒。
返回其总持续时间(以秒为单位)可被 60 整除的歌曲对的数量。形式上,我们希望索引的数字 i 和 j 满足 i < j 且有 (time[i] + time[j]) % 60 == 0。
示例 1:
输入:[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:
输入:[60,60,60]
输出:3
解释:所有三对的总持续时间都是 120,可以被 60 整数。
提示:
1 <= time.length <= 60000
1 <= time[i] <= 500
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/pairs-of-songs-with-total-durations-divisible-by-60
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
```cpp
class Solution {
public:
int numPairsDivisibleBy60(vector<int>& time) {
int s=0;
vector<int> a(60,0);
for(int i=0;i<time.size();i++)
a[time[i]%60]++;
s=s+a[0]*(a[0]-1)/2+a[30]*(a[30]-1)/2;
for(int j=1;j<30;j++)
s=s+a[j]*a[60-j];
return s;
}
};
作者:jie-yi
链接:https://leetcode-cn.com/problems/pairs-of-songs-with-total-durations-divisible-by-60/solution/si-lu-jian-dan-xian-qiu-mo-hou-zai-1-29yu-59-31pei/
数学:
- n个数 两两不重复排列组合有 (n-1)+…+3+2+1 组
- n%m∈[0~m-1]
- (a+b)|60 即 (1+59) (2+58) … (28+32) (29+31) (没有被算入0 30 )
- 若(a+b)%c=0则(a%c+b%c)%c=0(也是这个题的核心)
正文
题目让我们求其总持续时间可被 60 整除的歌曲对
两两一组,计算有多少组满足,60|(组1+组2)
"|"这个符号在数学里是整除的意思
如 3|6 就是说 6能被3整除
既然整除,就是➗60后 余数为0
也就是(a+b)%60 = 0
1.
我们目的是求两个相加之和能整除60
有这个公式
(a%c+b%c)%c=(a+b)%c
也就是说,只要分别求出每首歌的时间➗60的余数存到一个数组里
然后把那些两两相加可以整除60的进行排列就行了
for(int i=0;i<time.size();i++)
a[time[i]%60]++;
2.
n%60所得结果的范围一定在[0,59]
想要满足(a+b)%60=0, 则它们必须按照下面这样组合
(1+59) (2+58) … (28+32) (29+31)
所以有:
for(int j=1;j<30;j++)
s=s+a[j]*a[60-j];
例如:
a[1]=2;(代表有两个数除60 余1)
a[59] = 1;(代表有一个数除60 余59)
显然 他们能组成 1*2个 组合
3.
注意: ➗60余数为0和30的数没有被算入
单独计算余数为 0 有多少组(两两相加可以整除60) 和 余数为30 (两两相加可以整除60)对数
s=s+a[0]*(a[0]-1)/2+a[30]*(a[30]-1)/2;
这是根据 n(n-1)/2 = 1+2+3+…+(n-1)来的
假如能整除60的数为5个, 即a[0] = 5
那这五个数能组成的(下标)不重复组合的个数为 5(5-1)/2=4+3+2+1