LeetCode破解之相对名次

438 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 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一一替换。