红包运气排行榜问题题解
题目描述
小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. 问题分析
这是一个排序问题,但需要考虑两个关键因素:
- 主要排序依据是抢到的红包金额(降序)
- 当金额相同时,需要考虑抢红包的原始顺序(升序)
2. 解决方案
我们可以通过以下步骤解决这个问题:
- 创建数据结构存储每个人的信息(姓名、金额、原始顺序)
- 使用自定义排序规则对数据进行排序
- 提取排序后的姓名列表
3. 具体实现思路
- 使用字典存储每个人的信息:
- 键为参与者的索引
- 值为包含金额、姓名和原始顺序的字典
- 定义排序规则:
- 首先按金额降序排序
- 金额相同时按原始顺序升序排序
- 使用Python的sorted函数配合自定义排序键进行排序
- 从排序结果中提取姓名列表
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]
代码详解
-
创建字典存储信息:
- 使用person_dict存储每个人的信息
- 包含金额(v)、原始索引(idx)和姓名(name)
-
构建数据结构:
- 遍历输入数据,构建完整的信息字典
- 对于重复出现的名字,累加其金额
-
自定义排序规则:
- 使用元组(-p['v'], p['idx'])作为排序键
- 负号实现金额降序排序
- 原始索引实现相同金额时的升序排序
-
结果处理:
- 使用列表推导式提取排序后的姓名列表
- 保持排序顺序不变