一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第19天,点击查看活动详情。
题目描述
给你一个长度为 n 的整数数组 score ,其中 score[i] 是第 i 位运动员在比赛中的得分。所有得分都 互不相同 。
运动员将根据得分 决定名次 ,其中名次第 1 的运动员得分最高,名次第 2 的运动员得分第 2 高,依此类推。运动员的名次决定了他们的获奖情况:
名次第 1 的运动员获金牌 "Gold Medal" 。 名次第 2 的运动员获银牌 "Silver Medal" 。 名次第 3 的运动员获铜牌 "Bronze Medal" 。 从名次第 4 到第 n 的运动员,只能获得他们的名次编号(即,名次第 x 的运动员获得编号 "x")。 使用长度为 n 的数组 answer 返回获奖,其中 answer[i] 是第 i 位运动员的获奖情况。
示例 1:
输入:score = [5,4,3,2,1]
输出:["Gold Medal","Silver Medal","Bronze Medal","4","5"]
解释:名次为 [1st, 2nd, 3rd, 4th, 5th] 。
解题思路
分析:这里面是我可以使用优先队列进行排序,存储数组,
int[0]表示分数,int[1]表示位置,按照分数排序即可,最后对前三位进行特殊处理即可,或者用TreeMap,TreeMap会对key值自动升序的特性编写的,因为分数互不相同,所以key存放成绩,value存放下标。
class Solution {
public String[] findRelativeRanks(int[] score) {
String[] ret = new String[score.length];
String[] desc = {"Gold Medal", "Silver Medal", "Bronze Medal"};
PriorityQueue<int[]> queue = new PriorityQueue<>((o1, o2) -> o2[0] - o1[0]);
for (int i = 0; i < score.length; i++) {
queue.add(new int[]{score[i], i});
}
for (int i = 0; i < score.length; i++) {
int[] grid = queue.poll();
if (i < 3) {
ret[grid[1]] = desc[i];
} else {
ret[grid[1]] = Integer.toString(i + 1);
}
}
return ret;
}
}
分析:这里还有另外一种思路,行业上面不太不一样,也没有用到map,时间效率可能低一下,但是思路编写起来比较简单。
1、默认给数组进行排名是从第一名,依次往后排; 2、遍历数组,采用冒泡排序,同时下标数组也同步排序; 3、最后下标数组的值代表是最终的排名,再利用排名规则,输出结果即可;
class Solution {
public String[] findRelativeRanks(int[] score) {
int [] a=new int[score.length];
for(int i=0;i<score.length;i++){
int t=1;
for(int j=0;j<score.length;j++){
if(i==j)
continue;
if(score[i]<score[j]){
t++;
}
}
a[i]=t;
}
String []b=new String[a.length];
for(int i=0;i<a.length;i++)
{
if(a[i]<=3){
if(a[i]==1){
b[i]="Gold Medal";
}if(a[i]==2)b[i]="Silver Medal";
if(a[i]==3)b[i]="Bronze Medal";
}
else{
b[i]=Integer.toString(a[i]);
}
}
return b;
}
}
这题目需要注意的点是:给定集合数据不重复;最终的结果是自大向小排序的名词,前 3 名的输出要特殊处理。这里的最好的处理就是将给定集合转换为带索引位置信息的集合;对新集合按照成绩逆序排列,依次公布名词。
我一开始的时候,准备直接利用获取原nums的索引进行替换,发现有点慢,然后用字典保存值与对应的名次再遍历nums一一替换。