LeetCode/总持续时间可被 60 整除的歌曲

Posted 929code

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode/总持续时间可被 60 整除的歌曲相关的知识,希望对你有一定的参考价值。

在歌曲列表中,第 i 首歌曲的持续时间为 time[i] 秒
返回其总持续时间(以秒为单位)可被 60 整除的歌曲对的数量

1. 打表(数据量较小)

列出60的倍数+哈希查找
class Solution 
public:
    int numPairsDivisibleBy60(vector<int>& time) 
        int n = time.size();
        long count = 0;
        map<int,int> m;
        for(int i =0;i<n;i++)
            m[time[i]]++;
        int cur = 0;
        vector<int> nums;
        for(int i=0;i<20;i++)
            cur+=60;
            nums.push_back(cur);
        
        for(auto it = m.begin();it!=m.end();it++)//从小到大遍历
            auto index = lower_bound(nums.begin(),nums.end(),it->first);//找第一个大于等于的值
            while(index!=nums.end())
                int sub = *index - it->first;
                if(sub==it->first) count += calculate(it->second-1)*2;
                else if(m.count(sub)) count += it->second*m[sub];
                index++;
            
        
        return count/2;
    
    long calculate(int n)
        long  res = 0;
        while(n!=0)
            res+=n;
            n--;
        
        return res;
    
;

2. 预先取模

先对所有数据取模减少计算量

class Solution 
public:
    int numPairsDivisibleBy60(vector<int>& time) 
        int n = time.size();
        int count = 0;
        map<int,int> m;
        for(int i =0;i<n;i++)
            time[i] = time[i]%60;
            m[time[i]]++;
        
        for(auto it = m.begin();it!=m.end()&&it->first<=30;it++)//从小到大遍历
                int sub = 60 - it->first;
                if(it->first==30||it->first==0) count += calculate(it->second-1);
                else if(m.count(sub))  count += it->second*m[sub];
            
            return count;
        
    long calculate(int n)
        return (long)(1+n)*n/2;
    
;
优化写法(数组作哈希表)
class Solution 
public:
    int numPairsDivisibleBy60(vector<int>& time) 
        vector<int> cnt(60);
        for (int t : time) 
            cnt[t % 60]++;
        long long res = 0;
        for (int i = 1; i < 30; i++) 
            res += cnt[i] * cnt[60 - i];      
        res += (long long)cnt[0] * (cnt[0] - 1) / 2 + (long long)cnt[30] * (cnt[30] - 1) / 2;
        return (int)res;
    
;

力扣(LeetCode) 1010. 总持续时间可被 60 整除的歌曲

在歌曲列表中,第 i 首歌曲的持续时间为 time[i] 秒。

返回其总持续时间(以秒为单位)可被 60 整除的歌曲对的数量。形式上,我们希望索引的数字 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 整数。

提示:

1 <= time.length <= 60000
1 <= time[i] <= 500

Java版 时间复杂度O(n)

class Solution {
    public int numPairsDivisibleBy60(int[] time) {
        int i,total=0,len=time.length; 
        int[] res = new int[60]; // 整除60余数 初始化默认值0
        for(i=0;i<len;i++) {
            res[time[i]%60]++;
        }
         //余数为0 的统计 和余数为30 的单独统计
        total += res[0]*(res[0]-1)/2 + res[30]*(res[30]-1)/2;
        //余数为 1~59的统计(不包括30)
        for(i=1;i<30;i++) {
            total += res[i] * res[60-i] ; 
        }
        return total;
    }
}

C语言版 时间复杂度O(n*n) 提交超时

int numPairsDivisibleBy60(int* time, int timeSize) {
        int i,j,total=0;
		for (i = 0; i < timeSize-1; i++) {
			for (j = i+1; j < timeSize; j++) {
				if((time[i]+time[j])%60 == 0) {
					total++;
				}
			}
		}
        return total;
}

C语言版 时间复杂度O(n)

int numPairsDivisibleBy60(int* time, int timeSize) {
        int i,total=0;
        int res[60] = {0}; // 整除60余数 初始化默认值0
        for(i=0;i<timeSize;i++) {
            res[time[i]%60]++;
        }
         //余数为0 的统计 和余数为30 的单独统计
        total += res[0]*(res[0]-1)/2 + res[30]*(res[30]-1)/2;
        //余数为 1~59的统计(不包括30)
        for(i=1;i<30;i++) {
            total += res[i] * res[60-i] ; 
        }
        return total;
}

运行结果

以上是关于LeetCode/总持续时间可被 60 整除的歌曲的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 1010. 总持续时间可被 60 整除的歌曲 Java

LeetCode 1010. 总持续时间可被 60 整除的歌曲 Java

Leetcode-1013 Pairs of Songs With Total Durations Divisible by 60(总持续时间可被 60 整除的歌曲)

1010. 总持续时间可被 60 整除的歌曲

leetcode 974. 和可被 K 整除的子数组

Leetcode 1262. 可被三整除的最大和