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

94 阅读4分钟

题目描述

小C参与了一场抢红包的游戏,现在他想要对所有参与抢红包的人进行一次运气排名。排名规则如下:

  1. 抢到的金额越多,排名越靠前。
  2. 如果两个人抢到的金额相同,则按照他们抢红包的顺序进行排名。比如,如果小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. 数据存储准备

    • 创建一个List<Person>类型的列表people,用于存储人员信息。这是一个包含自定义Person类对象的列表,每个对象代表一个人,包含姓名、金额和索引信息。
    • 创建一个Map<String, Person>类型的映射map,以人员姓名为键,对应Person对象为值。这个映射的作用是方便快速查找和更新人员信息,避免重复创建相同姓名的Person对象。
List<Person> people = new ArrayList<>();
Map<String, Person> map = new HashMap<>();
  1. 填充数据

    • 遍历输入的人员姓名列表s和金额列表x。对于每个人员,检查其姓名是否已经在map中。
    • 如果map中不包含当前人员的姓名,则创建一个新的Person对象,包含姓名、金额和索引信息。将这个新创建的对象添加到map中,并同时添加到people列表中。
    • 如果map中已经存在当前人员的姓名,说明该人员已经出现过,只需将其金额与当前输入的金额相加,更新对应的Person对象的金额信息。
for (int i = 0; i < n; i++) {
    if (!map.containsKey(s.get(i))) {
        // 创建新的 Person 对象并添加到 map 和 people 中
        map.put(s.get(i), new Person(s.get(i), x.get(i), i));
        people.add(new Person(s.get(i), x.get(i), i));
    } else {
        // 更新已存在的 Person 对象的金额信息
        Person person = map.get(s.get(i));
        person.setAmount(person.getAmount() + x.get(i));
    }
}
  1. 排序
    • map中的所有值(即所有的Person对象)提取到一个新的列表values中。
    • 使用自定义的比较器对values列表进行排序。比较规则为:如果两个人的金额不同,按照金额大小逆序排序;如果金额相同,则按照索引升序排序。
List<Person> values = new ArrayList<>(map.values());
Collections.sort(values, new Comparator<Person>() {
    @Override
    public int compare(Person o1, Person o2) {
        // 如果金额不同,按金额大小逆序
        if (o1.amount!= o2.getAmount()) {
            return o2.amount - o1.amount;
        }
        // 如果金额相同,按索引升序
        return o1.index - o2.index;
    }
});
  1. 提取结果
    • 创建一个结果列表result
    • 遍历排序后的values列表,将每个Person对象的姓名添加到result列表中。
List<String> result = new ArrayList<>();
for (Person person : values) {
    result.add(person.name);
}

解题代码

import java.util.*;

public class Main {
    public static List<String> solution(int n, List<String> s, List<Integer> x) {
        // 创建一个数据结构来存储每个人的信息
        List<Person> people = new ArrayList<>();
        // 创建一个Map用来表示每个人信息
        Map<String, Person> map = new HashMap<>();
        for (int i = 0; i < n; i++) {

        }
        // 填充数据
        for (int i = 0; i < n; i++) {
            // 如果map里的key没有,我们直接创建Perosn,然后向map里面添加数据即可
            if (!map.containsKey(s.get(i))) {
                map.put(s.get(i), new Person(s.get(i), x.get(i), i));
                people.add(new Person(s.get(i), x.get(i), i));
            } else {
                // 如果map里key已经有了,那么我们就将他的金额相加即可
                Person person = map.get(s.get(i));
                person.setAmount(person.getAmount() + x.get(i));
            }
        }
        // 我们只需要map的value来排序即可
        List<Person> values = new ArrayList<>(map.values());
        // 提取结果
        Collections.sort(values, new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                // 如果金额不同,那我们就按金额大小逆序
                if (o1.amount != o2.getAmount()) {
                    return o2.amount - o1.amount;
                }
                // 如果金额相同,那么我们就按索引升序
                return o1.index - o2.index;
            }
        });
        List<String> result = new ArrayList<>();
        // 遍历value,此时的value已经按照我们预想的排序排好了
        for (Person person : values) {
            // 按照题目要求,取出person里的name字段
            result.add(person.name);
        }
        System.out.println(result);
        return result;
    }

    // 定义一个类来存储每个人的信息
    static class Person {
        String name;
        int amount;
        int index;

        public Person(String name, int amount, int index) {
            this.name = name;
            this.amount = amount;
            this.index = index;
        }

        public void setAmount(int amount) {
            this.amount = amount;
        }

        public int getAmount() {
            return this.amount;
        }
    }

    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")));
    }
}

总结

基于人员姓名及金额信息,借助List<Person>Map<String, Person>存储管理数据,依姓名填充或更新金额。利用自定义比较器,先按金额逆序、金额相同按索引升序对人员对象List排序,再提取姓名生成结果List