• + 0 comments

    I believe this is the most optimized way to do it. Maybe we can remove the sort parts but it is still efficient. The key point is: the parameters are already sorted. Basically, it is possible to iterate through player list and keep the last compared index to not iterate all ranked array repeatedly.

    def climbingLeaderboard(ranked, player):
        ranked = list(set(ranked))
        scores = []
        length = len(ranked)
        
        player.reverse() # We use reversed list, we basically want the ranked and player arrays in the same order.
        matched = {}
        current_rank = 0
        for i in player:
    
            if matched.get(i, None): # remove duplicated computations.
                scores.append(matched[i])
                continue
    
            if current_rank >= length: # in last elements, it is likely to rank as last. 
                scores.append(current_rank + 1)
                continue
    
            if i > ranked[current_rank] or i == ranked[current_rank]: # if score is higher than current rank, assign the rank.
                matched[i] = current_rank + 1
                scores.append(current_rank + 1)
            else: # if it is lesser, we need an iteration since it is getting higher than current_rank. In short, we skip unnecessary parts. This is the optimization part.
                while current_rank < length and i < ranked[current_rank]:
                    current_rank += 1
                matched[i] = current_rank + 1
                scores.append(current_rank + 1)
        scores.reverse() # we have reversed the player list, so we need to reverse scores.
        print(scores)
        return scores