【问题标题】:Can't further optimize simple Python function无法进一步优化简单的 Python 函数
【发布时间】:2021-01-04 19:37:32
【问题描述】:

我无法对其进行足够的优化以使其在给定的时间范围内运行。

可以在此处 (https://www.hackerrank.com/challenges/climbing-the-leaderboard/problem) 找到完整的说明,但它们有点长。 我基本上有两个数组:一个是得分高的排行榜,另一个是玩家得分的列表。我必须输出另一个数组,其中包含每个分数的玩家排名(例如,第 1、第 4、第 8 为 1、4、8)。

这是我的功能,但功能很慢:

def climbingLeaderboard(ranked, player):
    rankings = []
    
    # Making it a set to remove duplicates
    ranked = list(set(ranked))

    # Sorting only once outside of loop
    ranked.sort()
    
    for score in player:
        # Duplicates must be avoided at all times
        if score not in ranked:
            # Used to avoid sorting at every iteration
            bisect.insort(ranked, score)

        # List was sorted ascending, but I need it descending
        # There were a -1 and +1 which offset each other in order to convert from index to ranking
        result = len(ranked) - ranked.index(score)
        rankings.append(result)

        # I don't fully get why, but this part can be omitted
        # rankings.remove(score)
        
    return rankings

我使用 bisect.insort() 来避免为循环的每次迭代对列表进行排序。 我想最重要的部分是转换为 set 然后再转换为 list,但老实说我不知道​​如何进一步优化它。

【问题讨论】:

    标签: python loops optimization


    【解决方案1】:

    删除排序和插入

    挑战引述:

    • 现有排行榜 ranked 是按降序排列的。
    • 玩家的分数 player 是按升序排列的。

    所以排序和插入都是多余的。排序是多余的,因为两个数组都已排序。插入是多余的,因为分数很密集(例如,并列第二名意味着两名球员都是第二名,而第三名没有跳过)并且球员分数是按升序排列的。

    使用索引来记住您最后的展示位置。

    基本上,对于每个玩家得分,您只想找到高于给定得分的得分计数。 如果删除冗余操作还不够,您可以记住第一个分数比上次高的地方,然后从那里开始。分别检查每个分数 - O(n^2) 因为您可能每次都需要检查所有排名。仅从您在上一次迭代中完成的位置进行检查 - O(n),因为您最多会检查 rank 数组一次。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-06
      • 2016-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-09
      相关资源
      最近更新 更多