← 返回编程题库
coding-rank-by-multi-key-tiebreak简单免费版2000ms未尝试

按多键优先级与次序对记录排序

Rank Records by Multi-Key Tie-Break Rule

开始编码

某排行榜服务按 score 给玩家排名(高分在前),但仅靠分数往往无法给出唯一确定的次序——榜首附近经常出现同分,题目要求一条完整、可文档化的 tie-break 链,确保两个用户在同一时刻刷新页面看到完全一致的排序。每条记录形如 {"name": "alice", "score": 100, "ts": 12345, "fee": 0.02}。tie-break 规则按优先级如下:**score 降序,然后 fee 升序,然后 ts 升序,最后 name 升序**。

实现 solution(records: list[dict]) -> list[dict]。用 key tuple (-score, fee, ts, name)records 排序并返回 *新* 列表——输入列表不能被原地修改。Python 的 sorted 配 tuple key 一次就能搞定:tuple 比较是字典序(从左到右,遇到第一个不等即返回),所以 tuple 每一位就是一层 tie-break;给 score 取负把这一层翻成降序,其他三层维持升序即可。Timsort 是 稳定排序,所以四键全相等的记录会保持原输入顺序——无需额外下标列兜底。

举例:solution([{"name": "a", "score": 10, "ts": 5, "fee": 0.1}, {"name": "b", "score": 10, "ts": 3, "fee": 0.05}, {"name": "c", "score": 12, "ts": 7, "fee": 0.2}]) 返回的顺序是 c, b, a:c 在最高优先级 score=12 > 10 上胜出;abscore=10 上打平,落到下一层 fee,b (0.05) 比 a (0.1) 更优。

实践背景

带显式 tie-break 顺序的多键排序是工具箱里最通用的排名原语——排行榜、top-N alpha 选股、按已实现 PnL 排序的微观结构成交后报告(并加上成本和到达时间作 tie-break)、按分数和面试轮次排序的招聘评估表、做市队列里的"价格-时间优先"本身就是两键排序。台桌上的标准写法正是这道题在隔离的那个套路:一次 sorted 加一个 tuple key,取负处理降序数值层,稳定性天然处理全等情况。其他写法——LSD 多次稳定排序,或者用 cmp_to_key 写自定义比较器——也能实现,但更慢,且当 reviewer 要按书面规范核对规则时也更难审计。

约束条件

  • 0 ≤ N = `len(records)` ≤ 100000
  • 每条记录是一个 dict,包含 `name (str), score (int), ts (int), fee (float)` 四个键,且四个键一定都存在
  • -1000000 ≤ `score` ≤ 1000000
  • 0 ≤ `ts` ≤ 1000000000
  • 0.0 ≤ `fee` ≤ 1.0 (float)
  • `name` 是字母数字字符串,长度 1..20;不同记录的 `name` 可能重复
  • 输出是包含原始 N 条记录的新 `list[dict]`,按 key `(-score, fee, ts, name)` 排序;输入列表不能被原地修改,dict 对象本身原样透传(同一对象,同一字段值)
  • 空输入返回 `[]`;当多条记录在四个排序字段上完全相等时,保持原输入顺序(Python 的稳定排序天然保证)

样例

Case 1 · statement-example: c outranks b outranks a by mixed tiers

输入: [[{"name":"a","score":10,"ts":5,"fee":0.1},{"name":"b","score":10,"ts":3,"fee":0.05},{"name":"c","score":12,"ts":7,"fee":0.2}]]

期望: [{"name":"c","score":12,"ts":7,"fee":0.2},{"name":"b","score":10,"ts":3,"fee":0.05},{"name":"a","score":10,"ts":5,"fee":0.1}]

c 在最高优先级 score=12 上胜出;a、b 在 score=10 上同分,落到 fee 层,b(0.05)优于 a(0.1)。

Case 2 · empty: zero records returns empty list

输入: [[]]

期望: []

空输入直接返回空列表。

Case 3 · single: one record passes through unchanged

输入: [[{"name":"solo","score":50,"ts":100,"fee":0.01}]]

期望: [{"name":"solo","score":50,"ts":100,"fee":0.01}]

只有一条记录,排序后位置不变。

最近提交

还没有提交记录。

编码区

实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。

加载编辑器...
计时0:00

默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。

Case 1 · statement-example: c outranks b outranks a by mixed tiers

输入: [[{"name":"a","score":10,"ts":5,"fee":0.1},{"name":"b","score":10,"ts":3,"fee":0.05},{"name":"c","score":12,"ts":7,"fee":0.2}]]

期望: [{"name":"c","score":12,"ts":7,"fee":0.2},{"name":"b","score":10,"ts":3,"fee":0.05},{"name":"a","score":10,"ts":5,"fee":0.1}]

c 在最高优先级 score=12 上胜出;a、b 在 score=10 上同分,落到 fee 层,b(0.05)优于 a(0.1)。

Case 2 · empty: zero records returns empty list

输入: [[]]

期望: []

空输入直接返回空列表。

Case 3 · single: one record passes through unchanged

输入: [[{"name":"solo","score":50,"ts":100,"fee":0.01}]]

期望: [{"name":"solo","score":50,"ts":100,"fee":0.01}]

只有一条记录,排序后位置不变。