Problem statement:
问题陈述:
In a list of songs, the i-th song has 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 with (time[i] + time[j]) % 60 == 0).
在歌曲列表中,第i首歌曲的持续时间为[i]秒。 返回其总持续时间(以秒为单位)可被60整除的歌曲对数 。 形式上,我们希望索引i <j的数量为( time [i] + time [j])%60 == 0 )。
Example:
例:
Input array:
10, 20, 30, 60, 80, 110, 120
Output:
Number of such pairs:
2
Pairs are:
10, 110
60, 120
Solution:
解:
Of course, there is a naïve solution using brute force technique. It's as simple as checking sum for every possible pair with a time complexity of O(n^2).
当然,存在使用暴力技术的幼稚解决方案。 就像检查每个可能的对的总和一样简单,时间复杂度为O(n ^ 2) 。
Efficient solution can be done using mathematical concepts of congruent modulo and combinatorics.
可以使用等价模和组合数学概念来完成有效的解决方案。
Let's revise what are the cases for a pair sum divisible by 60
让我们修改一下被60整除的对的情况
Both the numbers of the pair divisible by 60.
这对数字都可以被60整除。
The sum of their congruent modulo 60 is divisible by 60.
它们的全模60的和可被60整除。
So actually all the elements of the array can be grouped by congruent modulo.
Since it’s modulo 60.
Maximum remainder can be 59.
Remainders can be any number between 0 to 59.
因此,实际上,数组的所有元素都可以按全模来分组。
由于它是模60。
最大余数可以是59。
余数可以是0到59之间的任何数字。
We actually group all the elements based on modulo value.
实际上,我们根据模值对所有元素进行分组。
Declare group[60]={0}; //since their can be 60 possible remainders starting from 0 to 59
声明组[60] = {0}; //因为它们可以是0到59之间的60个余数
For I in input array
对于我在输入数组
group[i%60]++;
组[i%60] ++;
In this way our group is formed.
If group[j] is K, that simply means there are K elements in the array for each of them modulo 60 is j
这样,我们的小组就形成了。
如果group [j]为K ,则仅表示数组中有K个元素,每个元素的模60为j
So after grouping,
所以分组之后
10, 20, 30, 60, 80, 110, 120
group[10]=1 //10
group[20]=2 //20,80
group[30]=1 //30
group[50]=1 //110
group[0]=2 //60,120
Now we need to pick pairs from the group such that pair sum can be divisible by 60
现在我们需要从组中选择对,以便对和可以被60整除
How can we pick?
我们如何挑选?
Pick any from group[1] and group [59] //for first no remainder is 1, second remainder is 59 (1+59=60, divisible by 60)
从组[1]和组[59]中选择任意一个// //首先没有余数是1,第二个余数是59(1 + 59 = 60,可被60整除)
Pick any from group[2] and group [58] //for first no remainder is 2, second remainder is 58 (2+58=60, divisible by 60)
从组[2]和组[58]中选择任何一个,//首先没有余数是2,第二个余数是58(2 + 58 = 60,可被60整除)
Pick any from group[3] and group [57] //for first no remainder is 3, second remainder is 57(3+57=60, divisible by 60)
从组[3]和组[57]中选择任意一个//首先,没有余数是3,第二个余数是57(3 + 57 = 60,可被60整除)
......................continue till group[29] and group[31]......................
......................继续到第[29] 组和第[31]组 。 .....
Now two groups are remaining
group[30] and group[60]
This two groups are independent group
We can pick any two elements from group[30]
Same for group[0]
We are done...
现在剩下两组
小组[30]和小组[60]
这两个小组是独立小组
我们可以从组[30]中选择任意两个元素
群组相同[0]
我们完了...
For group[30] and group[0]
对于组[30]和组[0]
Possible combinations are (n/2) where n be the respective values for group[30] and group[0]
And for 1-29 condition
Pick one from first group and one from second group
Which is n1*n2 //n1=first group item no, n2=second group item no
可能的组合是(n / 2) ,其中n是group [30]和group [0]的相应值
对于1-29条件
从第一组中选择一个,从第二组中选择一个
这是n1 * n2 // // n1 =第一组项目编号, n2 =第二组项目编号
For the above example
对于上面的例子
Only combination possible is from
只能组合来自
group[10] and group[50] //1,1 elements respectively
group [10]和group [50] // 1,1个元素
group[0] //2 elements
group [0] // 2个元素
C++ implementation:
C ++实现:
#include <bits/stdc++.h>
using namespace std;
int numPairsDivisibleBy60(vector<int> time) {
//group[60] renamed as a[60]
int count=0;
int a[60]={0};
for(int i=0;i<time.size();i++){
a[time[i]%60]++;
}
int i=1,j=59;
while(i<j){ //for rules 1-29
count+=a[i]*a[j];
i++;
j--;
}
//for group[30] and group[0]
count+=(a[0]*(a[0]-1)/2)+(a[30]*(a[30]-1)/2);
return count;
}
int main(){
int n,item;
cout<<"Number of times to be entered:\n";
cin>>n;
cout<<"Enter times...\n";
vector<int> time;
while(n--){
cin>>item;
time.push_back(item);
}
cout<<"number of such pairs possible is: "
cout<<numPairsDivisibleBy60(time)<<endl;
return 0;
}
Output
输出量
Number of times to be entered:
7
Enter times...
10 20 30 60 80 110 120
number of such pairs possible is: 2
翻译自: https://www.includehelp.com/icp/pairs-of-songs-with-total-durations-divisible-by-60.aspx