积分排行榜
在游乐场游戏过程中, 用户希望跟踪自己在积分排行榜中的排名. 积分排行榜按如下方式排名:
最高积分的用户在积分榜上排名第一
相同积分有同样的排名, 否则排名往后加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)
如果各位大佬还有其他方法,也欢迎讨论。
在飞的小猪