青训营题目之红包运气排行榜| 豆包MarsCode AI 刷题

345 阅读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']

解题思路

以下是我对于这道题的解题思路

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'])

此时会得到三个测试案例完全正确,但是提交时就出现了错误

案例错误

9f8a4888838bc033568cf29d3dfc6863.png 此时,我真不知道错在哪里,然后我看了MarsCode的思路,如下:

  1. 数据结构选择

    • 你可以使用一个列表来存储每个参与者的信息,包括他们的名字和抢到的金额。
    • 为了方便排序,可以考虑使用元组 (amount, name) 来存储每个参与者的信息。
  2. 排序逻辑

    • 使用 Python 的 sorted 函数进行排序,排序的关键字可以是一个 lambda 函数,先按金额降序排序,再按名字的顺序(即抢红包的顺序)升序排序。
  3. 代码框架

    • 你可以先创建一个包含所有参与者信息的列表,然后对这个列表进行排序,最后提取出排序后的名字列表。

我发现和我的思路大致一致,后来看预期输出发现是一个人竟然能在同一个红包中抢多次,于是在代码中对相同名字(即同一个人)的总金额进行求和,然后再进行上述步骤,金额求和代码如下:

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抢红包是不一样的,解决了这个点这题就没什么难度了。