红包运气排行榜--js版解析

题目介绍:

小C参与了一场抢红包的游戏,现在他想要对所有参与抢红包的人进行一次运气排名。排名规则如下:抢到的金额越多,排名越靠前;如果两个人抢到的金额相同,则按照他们抢红包的顺序进行排名。比如,如果小C和小U抢到的金额相同,但小C比小U先抢,则小C排在小U前面。

具体实现步骤

  • 创建存储对象
    • let dic = {}; 创建一个空对象,用于模拟 Python 中的defaultdict。在后续步骤中,这个对象的键将是用户名,值是一个包含两个元素的数组,第一个元素用于存储抢到的总金额,第二个元素用于存储该用户第一次抢红包的索引(即顺序)。
  • 遍历更新信息
    • 通过for循环遍历每个用户的抢红包记录。对于每个用户:
      • let name = s[i]; 获取当前用户的名字。
      • let amount = x[i]; 获取当前用户抢到的金额。
      • 如果用户名不在dic对象中(通过!dic.hasOwnProperty(name)判断),则初始化其对应的金额为0,最早索引为Infinityif (!dic.hasOwnProperty(name)) { dic[name] = [0, Infinity]; })。这一步模拟了 Python 中defaultdict在访问不存在的键时自动创建并初始化的功能。
      • 接着更新dic对象中该用户的金额信息,通过dic[name][0] += amount; 将当前抢到的金额累加到总金额中。
      • 然后记录最早的索引,通过dic[name][1] = Math.min(dic[name][1], i); 取当前索引i和已记录的最早索引中的较小值,确保记录的是该用户第一次抢红包的索引,而不是随着循环不断变化的索引(如果直接使用dic[name][1] = i; 就会出现这种问题)。
  • 打包数据
    • 创建一个空数组res,然后通过for...in循环遍历dic对象,将每个用户的用户名、总金额和最早索引组成一个数组,并添加到res数组中(res.push([name, dic[name][0], dic[name][1]]);)。这样res数组就包含了所有用户的相关信息,以便后续排序。
  • 排序数据
    • 使用res.sort((a, b) => {... }); 对res数组进行排序。排序规则是:首先比较两个用户的总金额,如果b的总金额大于a的总金额,那么b应该排在a的前面,此时返回1;如果b的总金额小于a的总金额,那么a应该排在b的前面,此时返回-1;当两个用户的总金额相等时,再比较他们的最早索引,通过返回a[2] - b[2],如果a的最早索引小于b的最早索引,那么a应该排在b的前面,反之则b应该排在a的前面。这样就实现了按照金额降序排序,金额相同的情况下按照索引升序排序的规则。
  • 提取结果
    • 通过let ans = res.map(item => item[0]); 使用map方法遍历res数组,提取每个数组中的第一个元素(即用户名),组成一个新的数组ans,这个数组就是按照运气排名后的人员名字数组。

代码如下:

// 定义函数用于对抢红包人员进行运气排名
function solution(n, s, x) {
    // 使用对象模拟defaultdict的功能,键为用户名,值为包含总金额和最早索引的数组
    let dic = {};

    // 遍历每个用户的抢红包记录
    for (let i = 0; i < n; i++) {
        let name = s[i];
        let amount = x[i];

        // 如果用户名不在字典中,初始化其对应的金额为0,最早索引为Infinity
        if (!dic.hasOwnProperty(name)) {
            dic[name] = [0, Infinity];
        }

        // 更新字典中的金额
        dic[name][0] += amount;

        // 记录最早的索引,取当前索引和已记录的最早索引中的较小值
        dic[name][1] = Math.min(dic[name][1], i);
    }

    // 将红包信息和索引一起打包成数组,每个元素是包含用户名、总金额和最早索引的数组
    let res = [];
    for (let name in dic) {
        res.push([name, dic[name][0], dic[name][1]]);
    }

    // 按照金额降序排序,金额相同的情况下按照索引升序排序
    res.sort((a, b) => {
        if (b[1] > a[1]) {
            return 1;
        } else if (b[1] < a[1]) {
            return -1;
        } else {
            return a[2] - b[2];
        }
    });

    // 打印排序后的结果
    console.log(res);

    // 提取排序后的名字
    let ans = res.map(item => item[0]);

    return ans;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值