问题描述
小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.创建参与者信息列表:
participants = [(s[i], x[i], i) for i in range(n)]
首先创建了一个包含参与者信息的列表,每个元素是一个元组 (name, amount, index),其中 index 是每个人在原列表中的索引,用于在金额相同的情况下进行排序。
2.排序逻辑:
sorted_participants = sorted(participants, key=lambda p: (-p[1], p[2]))
然后使用 sorted 函数进行排序,key 参数定义了排序规则:先按金额降序排序,金额相同的情况下按索引升序排序。
3.提取排序后的名字列表:
result = [p[0] for p in sorted_participants]
最后按顺序提取返回result,即为运气排名
然后总的代码如下:
def solution(n: int, s: list, x: list) -> list:
# 创建一个包含参与者信息的列表,每个元素是一个元组 (name, amount, index)
participants = [(s[i], x[i], i) for i in range(n)]
# 使用sorted函数进行排序,自定义排序规则
sorted_participants = sorted(participants, key=lambda p: (-p[1], p[2]))
# 提取排序后的名字列表
result = [p[0] for p in sorted_participants]
return result
if __name__ == '__main__':
print(solution(4, ["a", "b", "c", "d"], [1, 2, 2, 1]) == ['b', 'c', 'a', 'd'])
print(solution(3, ["x", "y", "z"], [100, 200, 200]) == ['y', 'z', 'x'])
print(solution(5, ["m", "n", "o", "p", "q"], [50, 50, 30, 30, 20]) == ['m', 'n', 'o', 'p', 'q'])
此时会得到三个测试案例完全正确,但是提交时就出现了错误
案例错误
此时,我真不知道错在哪里,然后我看了MarsCode的思路,如下:
-
数据结构选择:
- 你可以使用一个列表来存储每个参与者的信息,包括他们的名字和抢到的金额。
- 为了方便排序,可以考虑使用元组
(amount, name)来存储每个参与者的信息。
-
排序逻辑:
- 使用 Python 的
sorted函数进行排序,排序的关键字可以是一个 lambda 函数,先按金额降序排序,再按名字的顺序(即抢红包的顺序)升序排序。
- 使用 Python 的
-
代码框架:
- 你可以先创建一个包含所有参与者信息的列表,然后对这个列表进行排序,最后提取出排序后的名字列表。
我发现和我的思路大致一致,后来看预期输出发现是一个人竟然能在同一个红包中抢多次,于是在代码中对相同名字(即同一个人)的总金额进行求和,然后再进行上述步骤,金额求和代码如下:
for i in range(n):
name = s[i]
amount = x[i]
if name in amount_dict:
amount_dict[name] += amount
else:
amount_dict[name] = amount
插入后总代码如下:
def solution(n: int, s: list, x: list) -> list:
# 创建一个字典来记录每个人的总金额
amount_dict = {}
for i in range(n):
name = s[i]
amount = x[i]
if name in amount_dict:
amount_dict[name] += amount
else:
amount_dict[name] = amount
# 创建一个包含参与者信息的列表,每个元素是一个元组 (name, total_amount, first_index)
participants = [(name, amount_dict[name], s.index(name)) for name in amount_dict]
# 使用sorted函数进行排序,自定义排序规则
sorted_participants = sorted(participants, key=lambda p: (-p[1], p[2]))
# 提取排序后的名字列表
result = [p[0] for p in sorted_participants]
return result
# 封装排序逻辑
def custom_sort_key(p):
return (-p[1], p[2])
if __name__ == '__main__':
print(solution(4, ["a", "b", "c", "d"], [1, 2, 2, 1]) == ['b', 'c', 'a', 'd'])
print(solution(3, ["x", "y", "z"], [100, 200, 200]) == ['y', 'z', 'x'])
print(solution(5, ["m", "n", "o", "p", "q"], [50, 50, 30, 30, 20]) == ['m', 'n', 'o', 'p', 'q'])
此时就可以顺利通过了,此题的难点就在于要注意红包是可以一个人反复抢的,这和我们平时的认知的vx抢红包是不一样的,解决了这个点这题就没什么难度了。