You are given a list of songs where the ith song has a duration of time[i] seconds.
Return the number of pairs of songs for which their total duration in seconds is divisible by 60. Formally, we want the number of indices i, j such that i < j with (time[i] + time[j]) % 60 == 0.
Example 1:
Input: time = [30,20,150,100,40]
Output: 3
Explanation: Three pairs have a total duration divisible by 60:
(time[0] = 30, time[2] = 150): total duration 180
(time[1] = 20, time[3] = 100): total duration 120
(time[1] = 20, time[4] = 40): total duration 60
给出time数组,找出其中有几对数字,使每对数字的和能被60整除
思路:
参考解法
利用余数的性质,一对数字的和能被60整除,那么它们余数的和也能被60整除。所以只要统计余数的和能被60整除的有多少对。
设数组count[60], 里面统计余数(time[i] % 60)能被60整除的个数 ,即每个元素单独被60整除的情况。
一对数字的和能被60整除,余数重复的情况有2种。
- 余数都是0
- 余数都是30
余数都是0时,歌曲有几对可用count[0] * (count[0] - 1) / 2计算,原理:假设count[0] = a, 用组合数 C a 2 C_a^2 Ca2, 即从a个数中取2个数的组合数。
同理余数都为30时,从余数为30的个数count[30]中,取2个数的组合。
count[30] * (count[30] - 1) / 2
剩下的是余数不重复的,从1到29遍历,这样就不用除2了
count[i] * count[60 - i]
public int numPairsDivisibleBy60(int[] time) {
if(time == null) return 0;
int result = 0;
int n = time.length;
int[] count = new int[60];
for(int i = 0; i < n; i++) {
count[time[i] % 60] ++;
}
//余数都是0
result += count[0] * (count[0] - 1) / 2;
//余数都是30
result += count[30] * (count[30] - 1) / 2;
//余数是1~29
for(int i = 1; i < 30; i++) {
result += count[i] * count[60 - i];
}
return result;
}