红包运气排行榜问题-题解

3 阅读3分钟

红包运气排行榜问题题解

题目描述

小C参与了一场抢红包的游戏,现在他想要对所有参与抢红包的人进行一次运气排名。排名规则如下:抢到的金额越多,排名越靠前;如果两个人抢到的金额相同,则按照他们抢红包的顺序进行排名。比如,如果小C和小U抢到的金额相同,但小C比小U先抢,则小C排在小U前面。

示例

示例 1:

输入: n = 4, s = ["a", "b", "c", "d"], x = [1, 2, 2, 1]
输出: ['b', 'c', 'a', 'd']

示例 2:

输入: n = 3, s = ["x", "y", "z"], x = [100, 200, 200]
输出: ['y', 'z', 'x']

示例 3:

输入: n = 5, s = ["m", "n", "o", "p", "q"], x = [50, 50, 30, 30, 20]
输出: ['m', 'n', 'o', 'p', 'q']

解题思路

1. 问题分析

这是一个排序问题,但需要考虑两个关键因素:

  1. 主要排序依据是抢到的红包金额(降序)
  2. 当金额相同时,需要考虑抢红包的原始顺序(升序)

2. 解决方案

我们可以通过以下步骤解决这个问题:

  1. 创建数据结构存储每个人的信息(姓名、金额、原始顺序)
  2. 使用自定义排序规则对数据进行排序
  3. 提取排序后的姓名列表

3. 具体实现思路

  1. 使用字典存储每个人的信息:
    • 键为参与者的索引
    • 值为包含金额、姓名和原始顺序的字典
  2. 定义排序规则:
    • 首先按金额降序排序
    • 金额相同时按原始顺序升序排序
  3. 使用Python的sorted函数配合自定义排序键进行排序
  4. 从排序结果中提取姓名列表

4. 复杂度分析

  • 时间复杂度:O(nlogn)
    • 主要来自排序操作
    • 构建数据结构需要O(n)
    • 提取结果需要O(n)
  • 空间复杂度:O(n)
    • 需要存储所有参与者的信息
    • 需要存储排序后的结果

代码实现

def solution(n, s, x):
    # 使用字典存储信息
    person_dict = {}
    
    # 构建字典
    for i in range(n):
        if s[i] in person_dict:
            p = person_dict[s[i]]
            person_dict[s[i]] = {
                **p,
                'v': p['v'] + float(x[i])
            }
        else:
            person_dict[s[i]] = {
                'idx': i,
                'v': float(x[i]),
                'name': s[i]
            }
    
    # 转换字典值为列表
    red_bag = list(person_dict.values())
    
    # 排序
    def sort_key(p):
        return (-p['v'], p['idx'])
    
    red_bag_sorted = sorted(red_bag, key=sort_key)
    
    # 返回排序后的名字列表
    return [p['name'] for p in red_bag_sorted]

代码详解

  1. 创建字典存储信息:

    • 使用person_dict存储每个人的信息
    • 包含金额(v)、原始索引(idx)和姓名(name)
  2. 构建数据结构:

    • 遍历输入数据,构建完整的信息字典
    • 对于重复出现的名字,累加其金额
  3. 自定义排序规则:

    • 使用元组(-p['v'], p['idx'])作为排序键
    • 负号实现金额降序排序
    • 原始索引实现相同金额时的升序排序
  4. 结果处理:

    • 使用列表推导式提取排序后的姓名列表
    • 保持排序顺序不变