49 红包运气排行榜 | 豆包MarsCode AI刷题

114 阅读2分钟

问题描述

题目链接

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

解决思路

  • 由于每个人都会一直抢红包,而且红包数量是不定的,这就需要用到了哈希表来存每个人已经收到了多少红包。
  • 但是题目中描述了如果两个人抢到的金额相同,按照他们抢红包的顺序进行排名,这就需要我们的哈希表有顺序,这就需要用到了java中的LinkedHashMap。
  • 分析到这里,我们就可以直接for循环将所有数据存到哈希表中,然后遍历哈希表得到最后的输出。

代码实现

static List<String> solution(int n, List<String> s, List<Integer> x) {
        LinkedHashMap<String, Integer> mp = new LinkedHashMap<>();
        for (int i = 0; i < n; i++) {
            if (!mp.containsKey(s.get(i)))
                mp.put(s.get(i), x.get(i));
            else
                mp.put(s.get(i), mp.get(s.get(i)) + x.get(i));
        }
        ArrayList<String> arr = new ArrayList<>();
        while (!mp.isEmpty()) {
            int max = Integer.MIN_VALUE;
            String name = null;
            for (Map.Entry<String, Integer> entry : mp.entrySet()) {
                if (entry.getValue() > max) {
                    name = entry.getKey();
                    max = entry.getValue();
                }
            }
            arr.add(name);
            mp.remove(name);
        }

        return arr;
    }

复杂度分析

  • 时间复杂度O(n^2),主要是因为每次查找最大值并移除的操作是 O(n),总共执行 n 次。
  • 空间复杂度O(n),主要是因为使用了 LinkedHashMap 和 ArrayList,每个存储 n 个元素。

优化建议

可以使用 Collections.sort 对 mp 进行排序,这样可以确保金额相同的情况下,顺序保持不变,并且时间复杂度可以降低到 O(n log n)

LinkedHashMap的使用建议

LinkedHashMap 是 Java 中功能强大且实用的集合类。在使用时,若需按插入顺序遍历元素且兼顾快速查找,它是不二之选。比如记录日志信息,以时间戳或日志级别为键,详细日志内容为值插入 LinkedHashMap,遍历时能依插入顺序清晰展示日志顺序。实现简单 LRU 缓存策略时,通过继承并合理配置构造函数及重写 removeEldestEntry 方法,可有效管理缓存空间。但要留意其内存占用,因维护双向链表会比普通 HashMap 耗费更多内存,在大数据量且内存紧张场景下需谨慎抉择。其查找性能虽与 HashMap 相近,平均时间复杂度为 O (1),但频繁插入删除时因链表维护会略有逊色。同时,键的不可变性至关重要,如同 HashMap,键的改变可能导致哈希码变化,从而引发数据获取异常,使用过程中必须保证键的稳定或正确处理键的变化情况,这样才能充分发挥 LinkedHashMap 的优势,让程序运行得更加高效、稳定。