题目简述
对所有参与抢红包的人进行一次运气排名(对数据进行排序)
规则如下:
- 抢到的金额越多,排名越靠前
- 如果两个人抢到的金额相同,则按照他们抢红包的顺序进行排名
输入:
- n :人数
- s数组 : 参与者抢红包的顺序
- x数组:参与者抢到的红包金额
输出:
- anss数组:参与者排名
思路
数据结构设计:
- 首先定义了一个
Person类来表示参与者,包含了三个属性:num(抢红包的顺序)、money(抢到的金额)、name(参与者的名字)。 - 通过实现
Comparable接口,重写了compareTo方法来定义参与者之间的比较规则。
public static class Person implements Comparable<Person>{
int num;
int money;
String name;
public Person(String name,int num,int money){
this.name=name;
this.num=num;
this.money=money;
}
public int compareTo(Person a){
if(a.money!=this.money){
return (a.money-this.money);
}
else{
return(this.num-a.num);
}
}
}
解题思路:
-
创建一个
Map来存储每个参与者抢到的金额,以及抢红包的顺序。 -
遍历参与者名字列表和对应的金额列表,更新每个参与者的总金额和抢红包的顺序。
-
将每个参与者的信息封装成
Person对象,并加入到一个列表中。 -
对列表中的
Person对象进行排序,根据抢到的金额从大到小排序,如果金额相同则按抢红包顺序从小到大排序。 -
最后将排序后的参与者名字放入一个新的列表中,作为最终的运气排名结果。
代码实现:
-
在
solution方法中,使用HashMap存储参与者的总金额和抢红包的顺序,以及一个HashSet存储参与者的名字。for(int i=0;i<s.size();i++){ if(q.containsKey(s.get(i))){ int oldvalue=q.get(s.get(i)); q.put(s.get(i), oldvalue+x.get(i)); } else{ q.put(s.get(i),x.get(i)); } if(!ii.containsKey(s.get(i))){ ii.put(s.get(i),i); } } -
遍历参与者名字列表,更新总金额和抢红包的顺序。
-
将参与者信息封装成
Person对象,加入到一个ArrayList中。
for(String name:ss){
Person a=new Person(name,ii.get(name),q.get(name));
i+=1;
ans.add(a);
}
-
对
ArrayList中的Person对象进行排序,根据compareTo方法定义的规则进行排序。 -
将排好序的参与者名字放入另一个
ArrayList中,作为最终的运气排名结果
ans.sort(null);
ArrayList<String> anss =new ArrayList<>();
for(Person p:ans){
anss.add(p.name);
}
return anss;
复杂度分析
时间复杂度分析
遍历参与者列表:
- 遍历参与者列表和金额列表的时间复杂度为 O(n),其中 n 为参与者的数量。
更新参与者信息:
- 在遍历过程中,更新参与者的总金额和抢红包的顺序的时间复杂度为 O(n)。
封装参与者信息:
- 将参与者信息封装成
Person对象并加入到列表的时间复杂度为 O(n)。
排序:
- 对
Person对象列表进行排序的时间复杂度为 O(nlogn),其中 n 为参与者的数量。
综合考虑,这段代码的时间复杂度为 O(nlogn),其中 n 为参与者的数量。
空间复杂度分析:
HashMap 和 HashSet:
- 使用了一个 HashMap 存储参与者的总金额和抢红包的顺序,一个 HashSet 存储参与者的名字,空间复杂度均为 O(n)。
ArrayList:
- 使用了一个 ArrayList 存储封装后的
Person对象,空间复杂度为 O(n)。
排序算法:
- 在排序过程中可能会使用额外的空间,但通常排序算法的空间复杂度为 O(1) 或 O(logn)。
综合考虑,这段代码的空间复杂度为 O(n),其中 n 为参与者的数量。