这是悦乐书的第248次更新,第261篇原创

01 看题和准备

今天介绍的是LeetCode算法题中Easy级别的第115题(顺位题号是506)。根据N名运动员的得分,找到他们的相对等级和得分最高的三个人,他们将获得奖牌:“金牌”,“银牌”和“铜牌”。例如:

输入:[5,4,3,2,1]

输出:["Gold Medal","Silver Medal","Bronze Medal","4","5"]

说明:前三名运动员获得前三名最高分,因此获得“Gold Medal”,“Silver Medal”和“Bronze Medal”。对于剩下的两名运动员,你只需要根据他们的分数输出他们的相对等级。

注意:

  • N是正整数,不超过10,000。

  • 所有运动员的得分都保证是独一无二的。

本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试。

02 第一种解法

这道题除了要排名外,还需要保持原来元素所在的位置不变,也就要求我们要把原数组中各元素的位置先保存起来。对此,我们可以使用HashMap来保存,key为元素值,value为其坐标。然后将数组排序,因为排序后是升序,所以需要我们反过来,从后往前开始排名,而新数组中的索引即为当前元素在map中的value值。

此解法的空间复杂度是O(n),时间复杂度是O(n log(n))。

public String[] findRelativeRanks(int[] nums) {
String[] arr = new String[nums.length];
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
for (int i=0; i<nums.length; i++) {
map.put(nums[i], i);
}
Arrays.sort(nums);
for (int i=nums.length-1; i >= 0; i--) {
if (i == nums.length-1) {
arr[map.get(nums[i])] = "Gold Medal";
} else if (i == nums.length-2) {
arr[map.get(nums[i])] = "Silver Medal";
} else if (i == nums.length-3) {
arr[map.get(nums[i])] = "Bronze Medal";
} else {
arr[map.get(nums[i])] = (nums.length-i)+"";
}
}
return arr;
}

03 第二种解法

对于上面的解法,我们可以使用一个新的数组来代替HashMap,将原来的数组复制一份出来,然后对复制出来的数组进行排序,然后遍历原数组的元素,使用二分法查找当前元素在复制数组中的索引,再使用数组长度减1后再减去该索引,得到当前元素的排名,然后按照金银铜以及名次的顺序依次写入字符串结果数组中去,并返回。

此解法的时间复杂度是O(n log2n),空间复杂度是O(n)。

public String[] findRelativeRanks2(int[] nums) {
String[] arr = new String[nums.length];
int[] copy = nums.clone();
Arrays.sort(copy);
for (int i=0; i< nums.length; i++) {
int rank = nums.length - 1 - Arrays.binarySearch(copy, nums[i]);
if (rank == 0) {
arr[i] = "Gold Medal";
} else if (rank == 1) {
arr[i] = "Silver Medal";
} else if (rank == 2) {
arr[i] = "Bronze Medal";
} else {
arr[i] = (rank+1)+"";
}
}
return arr;
}

04 第三种解法

我们也可以不对原数组进行排序,而使用一个新数组来保存原数组中各元素的索引值。

先遍历原数组找到最大元素的值,然后创建一个整型包装类数组,长度为最大值加1,然后再遍历一次原数组,新数组使用原数组的元素值作为索引,值为从0开始递增的整数。然后遍历新数组,因为新数组的长度是最大值加1,所以第一名肯定是新数组的最后一位元素。

因此我们从后往前开始遍历,同时还要借助一个新索引变量,作为结果数组的递增索引,如果当前元素不为null,并且新索引等于0,1,2,那么就按照金银铜的顺序写入结果数组,剩下的将新索引加1然后转为字符串写入结果数组即可。最后返回结果数组。

至于当中使用包装类来做数组(其原始值为null),是因为可以避免索引0的冲突,当然使用int(其原始值为0)也可以,但是需要在原索引的基础上加1,然后循环判断的时候就需要判断是否不等于0,在找到值后还需要再减1,还原成原来的索引值,而使用包装类就没这么麻烦。

此解法的时间复杂度是O(n),其中n为数组中最大元素的值,而非元素个数,因为使用了新数组,新数组的长度是数组中最大元素加1, 空间复杂度是O(n)。

public String[] findRelativeRanks3(int[] nums) {
String[] arr = new String[nums.length];
int max = -1;
for (int num : nums) {
if (num > max) {
max = num;
}
}
Integer[] numIndex = new Integer[max+1];
for (int i=0; i<nums.length; i++) {
numIndex[nums[i]] = i;
}
int index = 0;
for (int i=numIndex.length-1; i>=0; i--) {
if (numIndex[i] != null) {
if (index == 0) {
arr[numIndex[i]] = "Gold Medal";
} else if (index == 1) {
arr[numIndex[i]] = "Silver Medal";
} else if (index == 2) {
arr[numIndex[i]] = "Bronze Medal";
} else {
arr[numIndex[i]] = (index+1)+"";
}
index++;
}
}
return arr;
}

05 小结

算法专题目前已日更超过三个月,算法题文章115+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。

以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!

LeetCode算法题-Relative Ranks(Java实现)的更多相关文章

  1. LeetCode算法题-Heaters(Java实现)

    这是悦乐书的第239次更新,第252篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第106题(顺位题号是475).冬天来了!您在比赛期间的第一份工作是设计一个固定温暖半径 ...

  2. LeetCode算法题-Sqrt(Java实现)

    这是悦乐书的第158次更新,第160篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第17题(顺位题号是69). 计算并返回x的平方根,其中x保证为非负整数. 由于返回类型 ...

  3. LeetCode算法题-Subdomain Visit Count(Java实现)

    这是悦乐书的第320次更新,第341篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第189题(顺位题号是811).像"discuss.leetcode.com& ...

  4. LeetCode算法题-Number of Lines To Write String(Java实现)

    这是悦乐书的第319次更新,第340篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第188题(顺位题号是806).我们要将给定字符串S的字母从左到右写成行.每行最大宽度为 ...

  5. LeetCode算法题-Unique Morse Code Words(Java实现)

    这是悦乐书的第318次更新,第339篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第186题(顺位题号是804).国际莫尔斯电码定义了一种标准编码,其中每个字母映射到一系 ...

  6. LeetCode算法题-Rotate String(Java实现)

    这是悦乐书的第317次更新,第338篇原创 在开始今天的算法题前,说几句,今天是世界读书日,推荐两本书给大家,<终身成长>和<禅与摩托车维修艺术>,值得好好阅读和反复阅读. 0 ...

  7. LeetCode算法题-Rotated Digits(Java实现)

    这是悦乐书的第316次更新,第337篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第185题(顺位题号是788).如果一个数字经过180度旋转后,变成了一个与原数字不同的 ...

  8. LeetCode算法题-Letter Case Permutation(Java实现)

    这是悦乐书的第315次更新,第336篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第184题(顺位题号是784).给定一个字符串S,将每个字母单独转换为小写或大写以创建另 ...

  9. LeetCode算法题-Minimum Distance Between BST Nodes(Java实现-四种解法)

    这是悦乐书的第314次更新,第335篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第183题(顺位题号是783).给定具有根节点值的二叉搜索树(BST),返回树中任何两个 ...

随机推荐

  1. 免费SSL证书(支持1.0、1.1、1.2)

    由于公司要开发微信小程序,而微信小程序的接口需要https协议的,并且要支持TLS1.0.TLS1.1.TLS1.2.如果仅仅是为了开发小程序,安全等级又不用太高,可以选择免费的SSL证书 在这里选择 ...

  2. tensorflow机器学习模型的跨平台上线

    在用PMML实现机器学习模型的跨平台上线中,我们讨论了使用PMML文件来实现跨平台模型上线的方法,这个方法当然也适用于tensorflow生成的模型,但是由于tensorflow模型往往较大,使用无法 ...

  3. Asp.Net SignalR 多平台的Client与Server

    多平台 SignalR在.Net的大环境下都可以做到即时通讯,也就是说都可以使用,客户端也不仅是js.下面就来一个控制台的Client 我们需要在nuget上下载包 Microsoft.AspNet. ...

  4. NSCTF web200

    Topic Link http://ctf5.shiyanbar.com/web/web200.jpg 1) 分析代码可知a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQ ...

  5. leetcode — clone-graph

    import java.util.*; /** * Source : https://oj.leetcode.com/problems/clone-graph/ * * * Clone an undi ...

  6. linux进程管理和系统状态常用命令简介

    1 进程管理简介 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础 2 常用命令 2.1 pstree 2.1.1 功能描 ...

  7. Linux基础知识第四讲,文件内容命令

    目录 一丶常用命令 1.cat命令演示以及常用选项 2.grep 搜索命令的使用 3.echo 以及 重定向的使用 4.管道概念 一丶常用命令 序号 命令 对应英文 作用 01 cat 文件名 con ...

  8. eclipse 创建maven 项目 动态web工程完整示例

    需求表均同springmvc案例 此处只是使用maven 注意,以下所有需要建立在你的eclipse等已经集成配置好了maven了,说白了就是新建项目的时候已经可以找到maven了 没有的话需要安装m ...

  9. Ruby数组(1):基本用法

    数组 Ruby中的数组是一个容器,数组中的每个元素都是一个对象的引用. 注意,Array类中包含了Enumerable模块,所以Enumerable中的方法也都能使用,例如Enumerable中的re ...

  10. WPF TextBox/TextBlock 文本超出显示时,文本靠右显示

    文本框显示 文本框正常显示: 文本框超出区域显示: 实现方案 判断文本框是否超出区域 请见<TextBlock IsTextTrimmed 判断文本是否超出> 设置文本布局显示 1. Fl ...