红包运气排行榜python解法 | 豆包MarsCode AI刷题

135 阅读4分钟

红包运气排行榜

问题描述

小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​列表索引值。

具体实现

  1. s​x​ 结合:通过 zip(s, x)​ 将两个列表配对,并用一个字典 merged​ 存储每个 s​ 元素对应的 x​ 值。如果 s​ 中的元素已经存在,就更新 merged​ 中的值,累加新的值求和。

  2. 排序:用 sorted()​ 对字典的键值对列表 unique_combined​ 进行排序。排序的规则是:

    • 根据 x​(即数字值)降序排序:-y[1]​ 实现了降序。
    • 如果 x​ 的值相同,则按 s​ 中原始顺序排序:s.index(y[0])​ 保证了在 s​ 中相同元素的顺序。
  3. 提取排序后的 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

核心代码解释

  1. ​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​ 列表中的位置进行升序排序。

时间复杂度分析:

  1. 字典合并过程:

    • 这个循环遍历了s​x​ 列表中的所有元素,假设列表长度为 n​
    • ​zip(s, x)​ 的时间复杂度是 O(n),因为它需要遍历 s​x​ 中的每个元素并将它们合并成元组。
    • ​item1 not in merged​ merged[item1] = item2​merged[item1] += item2​ 是字典的操作,查找和插入(或更新)字典的时间复杂度为 O(1)。

    所以,这部分的时间复杂度是 O(n)。

  2. 排序:

    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)。