红包运气排行榜

问题描述

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


问题分解

具体来说,排名规则包括以下几点:

  1. 金额优先:抢到的总金额越多,排名越靠前。
  2. 顺序优先:如果两位参与者的总金额相同,则按照抢红包的先后顺序排名。

需求分析与设计

1. 需求分解
为了实现该排名系统,我们需要解决以下几个核心问题:

  • 统计每个用户抢到的红包总金额。
  • 在金额相同时,维护用户的抢红包顺序。
  • 根据上述规则输出最终的排名列表。

2. 数据结构选择
为了解决这些问题,我们可以选择以下数据结构:

  • 使用 Map<String, Integer> 来存储用户及其对应的红包总金额,其中键为用户名,值为金额。
  • 使用 LinkedHashMap 保证插入顺序,这对于按抢红包顺序排名尤为重要。
  • 通过 ListStream 实现排序逻辑。

3. 排序规则
排序的核心逻辑分为两步:

  • 先比较金额大小,金额大的排在前面。
  • 如果金额相同,则保持用户的插入顺序。

代码实现

import java.util.*;
import java.util.stream.Collectors;

public class Main {
    public static List<String> solution(int n, List<String> s, List<Integer> x) {
        // 使用 Map 统计每个用户的总金额
        Map<String, Integer> map = new LinkedHashMap<>();
        for (int i = 0; i < s.size(); i++) {
            map.put(s.get(i), map.getOrDefault(s.get(i), 0) + x.get(i));
        }

        // 根据金额降序排序,金额相同时按插入顺序排序(使用 LinkedHashMap 保证顺序)
        return map.entrySet().stream()
                .sorted((a, b) -> {
                    if (!b.getValue().equals(a.getValue())) {
                        return b.getValue() - a.getValue(); // 按金额降序
                    } else {
                        return 0; // 保持原顺序
                    }
                })
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());
    }

    public static void main(String[] args) {
        System.out.println(solution(4, Arrays.asList("a", "b", "c", "d"), Arrays.asList(1, 2, 2, 1)).equals(Arrays.asList("b", "c", "a", "d")));
        System.out.println(solution(3, Arrays.asList("x", "y", "z"), Arrays.asList(100, 200, 200)).equals(Arrays.asList("y", "z", "x")));
        System.out.println(solution(5, Arrays.asList("m", "n", "o", "p", "q"), Arrays.asList(50, 50, 30, 30, 20)).equals(Arrays.asList("m", "n", "o", "p", "q")));
    }
}

坑点与优化

1. 用户抢多个红包的处理
一个用户可能在活动中抢到多个红包,因此需要将其金额进行累加。为了实现这一点,可以在遍历用户数据时,通过 MapgetOrDefault 方法直接完成金额的累加逻辑。这里需要注意的是,如果使用的 Map 没有保证插入顺序(比如普通的 HashMap),则排序结果可能会与期望不一致。

2. 数据排序的稳定性
在排序过程中,可能会涉及到金额相同的用户。为了解决金额相同时的顺序问题,选择 LinkedHashMap 是关键。该数据结构能够按照插入顺序保存用户数据,从而确保排名结果的稳定性。

3. 性能优化
在实际应用中,参与抢红包的用户可能达到成千上万,这对算法性能提出了较高要求。以下是优化点:

  • 时间复杂度分析:用户数据的遍历为 (O(n)),排序为 (O(k *log k)),其中 (n) 是红包总数,(k) 是用户数。总体复杂度为 (O(n + k *log k))。
  • 空间复杂度优化:利用流式操作减少中间结果的存储开销。

博客首页:总是学不会

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值