Hackerrank ClimbingLeaderboard函数运行异常问题排查
Climbing the Leaderboard 代码错误修复
你的代码存在两个核心问题,导致无法得到正确结果:
- 二分查找逻辑与降序数组不匹配:排行榜是降序排列的,但你的二分条件按照升序数组逻辑编写,导致位置判断完全错误;
- 未处理分数不在排行榜的场景:仅当玩家分数与排行榜中某值完全相等时才记录排名,其他情况直接忽略,结果列表缺失元素。
问题具体拆解
- 第一个示例中,只有50能匹配到排行榜值,5、25、120均未被处理,导致结果为空/不完整;
- 第二个示例中,仅90匹配到对应排名,其余分数无处理逻辑,仅返回[2]。
修正后的代码
def climbingLeaderboard(ranked, player): # 预计算每个位置的排名 ranks = [] ranks.append(1) for i in range(1, len(ranked)): if ranked[i] == ranked[i-1]: ranks.append(ranks[i-1]) else: ranks.append(ranks[i-1] + 1) res = [] n = len(ranked) for score in player: lo = 0 hi = n - 1 current_rank = 0 while lo <= hi: mid = (lo + hi) // 2 if ranked[mid] == score: current_rank = ranks[mid] break # 降序数组中,分数大于mid值时,向左寻找更高排名区间 elif score > ranked[mid]: hi = mid - 1 # 分数小于mid值时,向右寻找更低排名区间 else: lo = mid + 1 # 处理未匹配到相等分数的情况 if current_rank == 0: if hi < 0: # 分数大于所有排行榜分数,排名第1 current_rank = 1 elif lo >= n: # 分数小于所有排行榜分数,排名为最后一名+1 current_rank = ranks[-1] + 1 else: # 分数介于两个排名之间,取右侧位置的排名 current_rank = ranks[lo] res.append(current_rank) return res
测试验证
- 输入:
ranked=[100,100,50,40,40,20,10],player=[5,25,50,120]
输出:[6,4,3,1],符合预期; - 输入:
ranked=[100,90,90,80,75,60],player=[50,65,77,90,102]
输出:[6,5,4,2,1],符合预期。
优化版本(去重后更高效)
可以先对排行榜去重,减少二分查找的数组长度,提升效率:
def climbingLeaderboard(ranked, player): # 去重并保持降序排列 unique_ranked = [] prev_score = None for score in ranked: if score != prev_score: unique_ranked.append(score) prev_score = score res = [] n = len(unique_ranked) for score in player: lo, hi = 0, n - 1 rank = n + 1 # 默认比所有分数小的排名 while lo <= hi: mid = (lo + hi) // 2 if unique_ranked[mid] == score: rank = mid + 1 break elif score > unique_ranked[mid]: hi = mid - 1 else: lo = mid + 1 # 处理未匹配情况 if rank == n + 1: rank = 1 if hi < 0 else lo + 1 res.append(rank) return res
内容的提问来源于stack exchange,提问作者easy translate
相关产品推荐
相关产品推荐

