Description:
In a list of songs, the i-th 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 with (time[i] + time[j]) % 60 == 0.
Example 1:
Input: [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
Example 2:
Input: [60,60,60]
Output: 3
Explanation: All three pairs have a total duration of 120, which is divisible by 60.
Note:
- 1 <= time.length <= 60000
- 1 <= time[i] <= 500
题意:给定一组歌曲的运行时间数组,计算所有可能的两手歌曲的组合,另其满足时间和可以整除60;
解法:首先,我们需要了解关于取余的一个模运算如下
(1)
(
a
+
b
)
%
p
=
(
a
%
p
+
b
%
p
)
%
p
(a + b) \% p = (a\%p +b\%p)\%p\tag{1}
(a+b)%p=(a%p+b%p)%p(1)
下面我们对这个等式进行证明:
假设
{
a
=
m
p
+
x
b
=
n
p
+
y
\begin{cases} a = mp + x \\ b = np + y \end{cases}
{a=mp+xb=np+y
(2)
等
式
左
边
=
(
a
+
b
)
%
p
=
(
(
m
p
+
x
)
+
(
n
p
+
y
)
)
%
p
=
(
(
m
+
n
)
p
+
(
x
+
y
)
)
%
p
=
(
x
+
y
)
%
p
\begin{aligned} 等式左边=&(a+b)\%p\\ =&((mp+x)+(np+y))\%p\\ =&((m+n)p+(x+y))\%p\\ =&(x+y)\%p \end{aligned}\tag{2}
等式左边====(a+b)%p((mp+x)+(np+y))%p((m+n)p+(x+y))%p(x+y)%p(2)
(3)
等
式
右
边
=
(
a
%
p
+
b
%
p
)
%
p
=
(
(
m
p
+
x
)
%
p
+
(
n
p
+
y
)
%
p
)
%
p
=
(
x
+
y
)
%
p
\begin{aligned} 等式右边=&(a\%p +b\%p)\%p\\ =&((mp+x)\%p+(np+y)\%p)\%p\\ =&(x+y)\%p \end{aligned}\tag{3}
等式右边===(a%p+b%p)%p((mp+x)%p+(np+y)%p)%p(x+y)%p(3)
由(2)(3)得证(1);
因此,我们要计算两首歌曲的时间
a
a
a和
b
b
b的时间总和可以被60整除,即
(
a
+
b
)
%
60
=
0
=
(
a
%
60
+
b
%
60
)
%
60
(a+b)\%60 = 0=(a\%60+b\%60)\%60
(a+b)%60=0=(a%60+b%60)%60,我们只需要利用散列表存储对60取余后,在[0,59]内歌曲的次数即可;
Java
class Solution {
public int numPairsDivisibleBy60(int[] time) {
int res = 0;
int[] table = new int[60];
for (int t: time) {
int mod = t % 60;
res += table[(60 - mod) % 60];
table[mod]++;
}
return res;
}
}