该函数必须返回数组songs
(整数数组,其中包括歌曲的长度,以秒为单位)中数字对的计数,以使形成的数字对总计整分钟。
long playlist(int songs_count, int *songs) {
int i, j, k = 0;
for (i = 0; i < songs_count; i++) {
for (j = i + 1; j < songs_count; j++)
if ((songs[i] + songs[j]) % 60 == 0)
k++;
}
return k;
}
答案 0 :(得分:6)
第一个直接方法是这样的:
seconds%60
的其余部分初始化为全零。a = array[i]
首歌曲和b = array[60-i]
首匹配的歌曲:num = a*b; k += num;
i==0
和i==30
,您需要特殊处理,因为匹配的歌曲位于同一数组元素中:num = a*(a-1);
这会将时间复杂度降低到O(N):
您需要
n
上循环以填充数组(在构建歌曲列表时可以完成一次)和0..30
上循环进行计算。这将导致O(N)+O(1)
编辑:根据您的规则(歌曲的顺序是否重要),您可能需要乘以2。
答案 1 :(得分:1)
如果秒的值较小,则可以使用哈希映射(在c ++中为unordered_map)来解决〜O(n)复杂性。
假设您知道该对的最大值是600秒,那么您可以让另一个数组存储这些值。
for(int i = 1; i <= 10; i++)
{
a[i-1] = i * 60;
}
//a[] = {60, 120, 180, 240, 300, 360, 420, 480, 540, 600};
unordered_map <int, int> mymap;
for(int i = 0; i < songs_count; i++)
{
mymap[i] = songs[i];
}
现在您可以将代码修改为(解决方案适用于C ++):
long playlist(int songs_count, int *songs)
{
int i, j, k = 0;
for(int i = 1; i <= 10; i++)
{
a[i-1] = i * 60;
}
//a[] = {60, 120, 180, 240, 300, 360, 420, 480, 540, 600};
unordered_map <int, int> mymap;
for(int i = 0; i < songs_count; i++)
{
mymap[i] = songs[i];
}
for (i = 0; i < songs_count; i++)
{
for (j = 0; j < n /*size of a*/; j++)
{
if (a[j] > songs[i] && mymap.find(a[j] - songs[i]) != mymap.end())
{
k++;
}
}
}
return k;
}
答案 2 :(得分:1)
您可以通过一种简单的方法将复杂度从 O(N 2 )降低到 O(N):
int a[60]
,为i
中的每个0
.. 59
计算持续时间为i
秒的歌曲总数分钟数。单程就足够了。i
,计算感兴趣的歌曲对的数量。再次需要一次通行证。假设一对歌曲必须具有不同的歌曲且顺序无所谓,这是一种实现方式:
long playlist(int songs_count, int *songs) {
long a[60] = { 0 };
int i;
long total;
for (i = 0; i < songs_count; i++)
a[songs[i] % 60]++;
total = (a[0] * (a[0] - 1) + a[30] * (a[30] - 1)) / 2;
for (i = 1; i <= 29; i++)
total += a[i] * a[60 - i];
return total;
}
如果顺序很重要,并且成对的歌曲可以有两次相同的歌曲,则计算是不同的:
long playlist(int songs_count, int *songs) {
long a[60] = { 0 };
int i;
long total;
for (i = 0; i < songs_count; i++)
a[songs[i] % 60]++;
total = 0;
for (i = 0; i < 60; i++)
total += a[i] * a[(60 - i) % 60];
return total;
}