1013. Pairs of Songs With Total Durations Divisible by 60(未完待续)

题目

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

错误的代码

使用O(n^2)的时间复杂度:使用i,j的嵌套循环:
虽然结果是正确的但时间超出了限制。

class Solution:
    def numPairsDivisibleBy60(self, time: List[int]) -> int:
        l=len(time)
        cn=0
        for i in range(l):
            for j in range(i+1,l):
                if (time[i]+time[j])%60==0:
                    cn+=1
        return cn

讨论区的代码

class Solution:
   def numPairsDivisibleBy60(self, time: List[int]) -> int:
       mod = [0] * 61
       for t in time:
           mod[-1] += mod[(60 - t % 60) % 60]
           mod[t % 60] += 1
       return mod[-1]

使用61个存储单位存储 60个求余得到的个数,最后一个存储单位存储计数。
注意:(60 - t % 60) % 60 ,其中如果不加外圈的求余 则60对应的是60,而实际应为0。
这样的话,只需要遍历一次,既可以求出结果,时间复杂度为O(n)。

学习一些有效提高效率的方法:

首先是正则表达式的学习:

我关于正则表达式的整理

collection中Counter的方法:

关于collections——容器数据类型

该模块实现了专门的容器数据类型,为Python的通用内置容器、dict、list、set和tuple提供了替代方案。

  • namedtuple() 生产函数对于创建元组子类使用命名域
  • deque 类列表的容器两端有快速的添加、出栈
  • ChainMap 类dict类,用于创建多个映射的单个视图
  • Counter dict子类对于计数哈希对象
  • OrderedDict dict子类,它记住已添加的订单项
  • defaultdict 调用工厂函数来提供缺失值的dict子类
  • UserDict 包装字典对象,使dict子类化更容易
  • UserList 包装列表对象,以便更容易地进行列表子类化
  • UserString 包装字符串对象,以便更容易地进行字符串子类化

暂时先研究一下counter和defaultdict
Counter对象
一个Counter工具被提供为了更方便和快速的计数,举个例子:

>>> # Tally occurrences of words in a list
>>> cnt = Counter()
>>> for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:
...     cnt[word] += 1
>>> cnt
Counter({'blue': 3, 'red': 2, 'green': 1})
>>> cnt
{3: 3, 4: 3, 5: 3, 6: 3}
>>> cnt={}
>>> for i in li:
	cnt[i]+=1
Traceback (most recent call last):
  File "<pyshell#13>", line 2, in <module>
    cnt[i]+=1
KeyError: 3
>>> # Find the ten most common words in Hamlet
>>> import re
>>> words = re.findall(r'\w+', open('hamlet.txt').read().lower())
>>> Counter(words).most_common(10)
[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),
 ('you', 554),  ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]

最高效的代码

from collections import Counter, defaultdict
class Solution:
    def numPairsDivisibleBy60(self, time: List[int]) -> int:
        counts = Counter(time)
        songs = defaultdict(int)

        for i, c in counts.items():
            songs[i % 60] += c
        targets = dict()
        res = 0
        for t in songs:
            if t in targets:
                res += songs[t] * targets[t]
            else:
                targets[60-t] = songs[t]
                
        for n in (30, 60):
            if targets.get(n, 0) > 1:
                res += targets[n] * (targets[n]-1) // 2
        return res
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值