我正在尝试在Hackerrank:https://www.hackerrank.com/challenges/climbing-the-leaderboard上解决此问题。问题陈述基本上指出,爱丽丝一个人和另一个爱丽丝有两组分数,当与其他玩家的得分相比时,我们必须使用dense ranking并显示爱丽丝的排名。在大型测试案例中,这给了我超时错误。我已经在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
答案 0 :(得分:3)
您的代码中有几个问题,但最重要的是以下问题。
...
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))
。在这种情况下,第一个位置对应最高得分,第二个位置对应第二最高得分,依此类推(每个问题陈述的初始数组按降序排列)。score
的爱丽丝,您都可以在数组中找到一个位置,使玩家的得分小于或等于score
。由于数组已排序,因此查找将花费O(log(n))
。例如,如果玩家的分数为40, 30, 10
,而爱丽丝的分数为35
,则找到的位置将为2
(对于算法描述,我认为第一个索引从{ {1}}),因为1
占据该位置,该位置是爱丽丝在排行榜中的 ACTUAL 位置,因此可以立即打印。因此,建议的解决方案的总体时间复杂度为30
。它将通过所有测试用例(我已经尝试过)。
答案 1 :(得分:1)
执行重复排序(a.sort(reverse = True))会花费大量时间。我有同样的问题。如果您阅读了该问题,您会发现分数是按顺序输入的(升序或降序)。 诀窍是利用这种固有的输入顺序。
还有一件事,由于嵌套循环,您的代码的时间复杂度为O(n ^ 2),而您所讨论的论坛可能是使用O(n)(不确定)进行的。