题目描述
小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']
- 输入:
解题思路
-
数据存储准备:
- 创建一个
List<Person>类型的列表people,用于存储人员信息。这是一个包含自定义Person类对象的列表,每个对象代表一个人,包含姓名、金额和索引信息。 - 创建一个
Map<String, Person>类型的映射map,以人员姓名为键,对应Person对象为值。这个映射的作用是方便快速查找和更新人员信息,避免重复创建相同姓名的Person对象。
- 创建一个
List<Person> people = new ArrayList<>();
Map<String, Person> map = new HashMap<>();
-
填充数据:
- 遍历输入的人员姓名列表
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));
}
}
- 排序:
- 将
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;
}
});
- 提取结果:
- 创建一个结果列表
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。