这是小川的第377次更新,第405篇原创
java
今天介绍的是LeetCode算法题中Easy级别的第239题(顺位题号是1010)。在歌曲列表中,第i首歌曲的持续时间为[i]秒。算法
返回其总持续时间(以秒为单位)可被60整除的歌曲对的数量,即当i <j
时,(time[i] + time[j])%60 == 0
。数组
例如:数据结构
输入:[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):总持续时间60code
输入:[60,60,60]
输出:3
说明:全部三对的总持续时间为120,可被60整除。get
注意:for循环
1 <= time.length <= 60000class
1 <= time[i] <= 500
数据结构与算法
暴力解法,使用两层for循环,可是会超时。循环
public int numPairsDivisibleBy60(int[] time) { int count = 0, n = time.length; for (int i=0; i<n; i++) { for (int j=i+1; j<n; j++) { if ((time[i]+time[j])%60 == 0) { count++; } } } return count; }
咱们须要将时间复杂度降到O(N)
,就得从新考虑time
中的元素值特性。
例如[30,20,150,100,40]
,其中30和150能够配对,20和100能够配对,20和40能够配对,这三对数之和均可以被60整除,那咱们能够事先就将这些数简化一步,对60取余,获得[30,20,30,40,40]
,新的数范围是[0,59]
,那么只要后面出现的数能在前面找到一个数,二者互补(即二者之和等于60的倍数),即60-temp = temp2;
temp2
在temp
的后面出现,变成伪代码就是60-time[i]%60
。
可是换到另一个例子上来看,[60,60,60]
,取余后变成了[0,0,0]
,再用60去减,发现没有能够配对的数,那咱们就再取余一次,即(60-time[i]%60)%60
,这样就能够处理那些自己是60的倍数的数。
思路:先对time
中的数用60进行取余运算,使用一个HashMap
,key
为新数组的元素值,value
为出现次数,遍历新数组中的元素num
,找到(60-num)%60
在HashMap
中的value
值,进行累加,最后输出。
public int numPairsDivisibleBy602(int[] time) { for (int i=0; i<time.length; i++) { time[i] %= 60; } int count = 0; Map<Integer, Integer> map = new HashMap<Integer,Integer>(); for (int num : time) { count += map.getOrDefault((60-num)%60, 0); map.put(num, map.getOrDefault(num, 0)+1); } return count; }
思路和第二种解法同样,将HashMap
换成int
数组。
public int numPairsDivisibleBy603(int[] time) { int[] count = new int[60]; int result = 0; for (int num : time) { result += count[(60-num%60)%60]; count[num%60]++; } return result; }
算法专题目前已连续日更超过七个月,算法题文章245+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。
以上就是所有内容,若是你们有什么好的解法思路、建议或者其余问题,能够下方留言交流,好看、留言、转发就是对我最大的回报和支持!