红包运气排行榜
问题描述
小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']
思路:
- 先把
s列表相同的字符串合并,并且对应的x列表的值求和。 - 对其进行排序,
x列表值大的排在前面,相等的话则比较对应的s列表索引值。
具体实现
-
将
s和x结合:通过zip(s, x)将两个列表配对,并用一个字典merged存储每个s元素对应的x值。如果s中的元素已经存在,就更新merged中的值,累加新的值求和。 -
排序:用
sorted()对字典的键值对列表unique_combined进行排序。排序的规则是:- 根据
x(即数字值)降序排序:-y[1]实现了降序。 - 如果
x的值相同,则按s中原始顺序排序:s.index(y[0])保证了在s中相同元素的顺序。
- 根据
-
提取排序后的
s:从排序后的元组中提取第一个元素(即s的元素)并返回排序后的列表。
def solution(n: int, s: list, x: list) -> list:
# 创建一个空字典 merged,用于存储合并后的结果
merged = {}
# 使用 zip 将两个列表 s 和 x 组合在一起,遍历每对元素
for item1, item2 in zip(s, x):
# 如果 item1 不在字典中,则将其添加,值为 item2
if item1 not in merged:
merged[item1] = item2
else:
# 如果 item1 已经在字典中,则将其值与 item2 相加
merged[item1] += item2
# 将字典 merged 转换成列表形式,每个元素是 (key, value) 形式的元组
unique_combined = list(merged.items())
# 对 unique_combined 列表进行排序:
# 1. 首先根据元组的第二个元素(即合并后的值)降序排序
# 2. 如果第二个元素相同,则根据该元素在原始列表 s 中的索引升序排序
sorted_combined = sorted(unique_combined, key=lambda y: (-y[1], s.index(y[0])))
# 提取排序后的结果,返回按排序后的顺序排列的 key(即原始列表 s 中的元素)
result = [y[0] for y in sorted_combined]
# 返回最终结果
return result
核心代码解释
-
sorted_combined = sorted(unique_combined, key=lambda y: (-y[1], s.index(y[0]))):对unique_combined列表进行排序:-
-y[1]:首先按值降序排序(y[1]是累加后的值,-y[1]实现降序排序)。 s.index(y[0]):如果值相同,则根据item1(即y[0])在原始s列表中的位置进行升序排序。
-
时间复杂度分析:
-
字典合并过程:
- 这个循环遍历了
s和x列表中的所有元素,假设列表长度为n。 zip(s, x)的时间复杂度是 O(n),因为它需要遍历s和x中的每个元素并将它们合并成元组。item1 not in merged和merged[item1] = item2或merged[item1] += item2是字典的操作,查找和插入(或更新)字典的时间复杂度为 O(1)。
所以,这部分的时间复杂度是 O(n)。
- 这个循环遍历了
-
排序:
sorted_combined = sorted(unique_combined, key=lambda y: (-y[1], s.index(y[0])))- 排序的时间复杂度是 O(n log n),其中 n 是待排序列表的长度。
- 但是需要注意的是,排序的 key 函数涉及到
s.index(y[0])。对于每个元素y[0],调用s.index(y[0])的时间复杂度是 O(n),因为它会遍历s列表来找到y[0]的索引。因此,排序时每次计算s.index(y[0])的时间复杂度是 O(n),所以整个排序过程的时间复杂度是 O(n log n) * O(n) = O(n^2)。
所以,这部分的时间复杂度是 O(n^2)。
因此,整体时间复杂度是O(n^2)。