【问题标题】:Which part of my code is causing a "Time-Out Error" and why?我的代码的哪一部分导致“超时错误”,为什么?
【发布时间】:2019-12-18 06:42:04
【问题描述】:

我正在尝试在 Hackerrank:https://www.hackerrank.com/challenges/climbing-the-leaderboard 上解决这个问题。问题陈述基本上表明有两组分数,一个是玩家,另一个是 Alice,我们必须使用 dense ranking 并显示 Alice 与其他玩家的分数相比的排名。它在大型测试用例上给了我超时错误。我已经在 Hackerrank 上使用了论坛建议并且成功了,但特别是我很想知道我的代码中的问题。这是我的代码:

class Dict(dict):

    def __init__(self):
        self=dict()

    def add(self,key,value):
        self[key]=value

def climbingLeaderboard(scores, alice):

    alice_rank=[]
    for i in range(len(alice)):
        scores.append(alice[i])
        a=list(set(scores))
        a.sort(reverse=True)
        obj=Dict()
        b=1
        for j in a:
            obj.add(j,b)
            b+=1
        if alice[i] in obj:
            alice_rank.append(obj[alice[i]])
    scores.remove(alice[i])        
    return alice_rank

【问题讨论】:

    标签: python python-3.x algorithm


    【解决方案1】:

    您的代码中有几个问题,但最重要的是以下问题。

    ...
    scores.append(alice[i])
    a=list(set(scores))
    a.sort(reverse=True)
    ...
    

    在每次迭代中,将 Alice 的分数添加到 scores,然后对 scores 进行排序。这里的成本已经是O(nlog(n)),其中n - scores 中的元素数。因此,您的总时间复杂度变为O(n*n*log(n))。这太多了,因为n 可以达到200000,因此对于您的解决方案,它可以达到200000*200000*log(200000) 操作。

    当然,还有一个问题:

    ...
    for j in a:
        obj.add(j,b)
        b+=1
    ...
    

    但它仍然没有上一个那么糟糕,因为循环时间复杂度是O(n)

    存在O(n*log(n)) 时间复杂度解决方案。我会给你一个总体思路,以便你自己轻松实现。

    • 如果您记得得分重复的玩家在排行榜中的位置相同,那么您可以在循环之前将scores 转换为不重复的数组,如list(set(scores))。在这种情况下,第一个位置对应于最高分,第二个对应于第二高分,依此类推(初始数组按问题陈述按降序排序)。
    • 根据上述步骤,对于 Alice 的每个score,您可以在数组中找到玩家得分小于或等于score 的位置。查找将采用O(log(n)),因为数组已排序。例如,如果玩家的分数是40, 30, 10,Alice 的分数是35,那么找到的位置将是2(对于算法描述,我认为第一个索引从1开始)为@987654344 @占据这个位置,这个位置是爱丽丝在排行榜的ACTUAL位置,所以可以马上打印出来。
    • 另一个提示 - 您可以使用 bisect 模块在数组中执行二进制搜索。

    因此,建议解决方案的整体时间复杂度为O(n*log(n))。它会通过所有的测试用例(我试过了)。

    【讨论】:

      【解决方案2】:

      执行重复排序 (a.sort(reverse=True)) 会消耗大量时间。我有同样的问题。如果您阅读问题,您会发现分数是按排序(升序或降序)输入的。 诀窍是利用这种固有的输入顺序。

      还有一点,由于嵌套循环,您的代码的时间复杂度为 O(n^2),而您所说的论坛可能会使用 O(n)(不确定)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-07
        • 2020-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多