在歌曲列表中,第 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 整数。
题解:
法一:暴力循环;两个for循环,计算time[i]与其之后的元素的和,除60取余,并判断。但是对长一点的数组会超时。
public int numPairsDivisibleBy60(int[] time) {
int len=time.length;
int count=0;
for(int i=0;i<len;i++){
for(int j=i+1;j<len;j++){
if((time[i]+time[j])%60==0){
count++;
}
}
}
return count;
}
法二:对time数组每一个元素模60,结果在0-59之间,结果对应放入另一大小为60的数组中,再对除第0和第30号元素之外的配对,即1-29号对应59-31号。
public int numPairsDivisibleBy60(int[] time) {
int count = 0;
int[] arr = new int[60];
for(int t : time) {
arr[t % 60] += 1; //对应下标
}
count += combination(arr[30], 2);
count += combination(arr[0], 2);
int i = 1, j = 59;
while(i < j) {
count += arr[i] * arr[j];
i++;
j--;
}
return count;
}
// 求组合数
public int combination(int n, int k) {
long result = 1;
for(int i = 1; i <= k; i++) {
result = result * (n - i + 1) / i;
}
return (int)result;
}