算法:积分排行榜

积分排行榜

在游乐场游戏过程中, 用户希望跟踪自己在积分排行榜中的排名. 积分排行榜按如下方式排名:
  最高积分的用户在积分榜上排名第一
  相同积分有同样的排名, 否则排名往后加1
比如, 给定数据:
  积分排行榜=[100, 90, 90, 80]
  用户每轮积分=[70, 10, 25]
那么积分榜的排名是1, 2, 2, 3. 用户每轮结束后的总积分是70, 80, 105. 用户每轮结束后的排行榜排名分别是4, 3, 1。也就是返回结果为[4,3,1]

算法描述:
给定参数:
  int[n] ranked: 积分排行榜,单调递减(有可能相等)且大于等于0
  int[m] scores: 用户每轮获得的积分, 每轮积分大于等于0
返回值:
  int[m]: 每轮结束后用户在积分排行榜中的排名
算法要求:
  复杂度: O(m+n)

示例一:
  ranked=[100, 100, 50 , 40, 40 , 20, 10]
  scores=[5, 20, 25, 70]
  返回int数组: [6, 4, 2,1]
示例二:
  ranked=[100, 90, 90, 80, 75, 60]
  scores=[50, 15, 12, 13, 12]
  返回int数组: [6, 5, 4, 2,1]

思路分析:

我们将第一次的得分与积分排行榜最后一名比较,如果比它小,则加到积分排行榜末端继续下一轮,如果等于它,则和积分排行榜最后一名同名次继续下一轮,如果大于它,则比较积分排行榜倒数第二名直到比较出来。
由此可见,第二轮循环要反向遍历积分排行榜。结束条件为遍历完排行榜。

def rank(ranked, scores):
    '''
    先将积分排行榜的排名算出来,之后将每轮打的分数,与积分排行榜后面一个排名
    :param ranked: [],  形如[100, 90, 90, 80, 75, 60], 积分排行榜
    :param scores: [],  形如[50, 15, 12, 13, 12]  每轮得分
    :return: res: [], [6, 5, 4, 2, 1] 每轮得分的积分排行
    '''
    num = [1]
    for i in range(1, len(ranked)):
        if ranked[i] == ranked[i -1]:
            num.append(num[-1])
        else:
            num.append(num[-1] + 1)
    score_sum = 0
    res=[]

    for i in range(len(scores)):
        score_sum += scores[i]
        for j in range(len(ranked) - 1, 0, -1):
            if score_sum < ranked[j]:  # 如果得分不如积分排行榜最后一名,则得分比最后一名还低
                res.append(num[j] + 1)
                ranked = ranked[:j]    # 更新排行榜,减少下轮不必要计算
                break
            elif score_sum == ranked[j]:  # 如果得分等于积分排行榜最后一名,则得分与最后一名同名次
                res.append(num[j])
                ranked = ranked[:j]    # 更新排行榜,减少下轮不必要计算
                break
        if score_sum > ranked[0]:  # 如果得分超过积分排行第一,则为头榜
            res.append(1)
    return res

例子

ranked = [100, 100, 50 , 40, 40 , 20, 10] 
scores= [5, 20, 25, 70]  
rank(ranked, scores)

如果各位大佬还有其他方法,也欢迎讨论。
在飞的小猪

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容