1.题目描述
问题描述
小M想要通过查看往届游戏比赛的排名来确定自己比赛的目标分数。他希望找到往 届比赛中排名第三的分数,作为自己的目标。具体规则如下: 1.如果分数中有三个或以上不同的分数,返回其中第三大的分数。 2.如果不同的分数只有两个或更少,那么小M将选择最大的分数作为他的目 标。 请你帮小M根据给定的分数数组计算目标分数。
示例1
输入: n = 2,nums =[1,2]输出: 2
示例2
输入:n= 4,nums =[2,2,3,1]输出:1
难度等级
简单
题目链接
[(MarsCode)]
2.解题思路
解法1
思路:题中说不同的数,然后分两种情况,第一种情况是至少有三个不同的数就找第三大的数,第二种是两个或两个以下的数找最大的数,我就想到把数组去重再排列。
步骤1 给nums去重
int len=n;//存储nums的长度,同时也是去重后新数组的长度
for(int i=0;i<len;i++){
for(int j=i+1;j<len;j++){
if (nums[i]==nums[j]){
nums[j]=nums[len-1];//把数组最后一个数放在j的位置
len--;//注意len-1位置的数值也在变
j--;//重新访问j位置数值,防止换来的数值也重复
}
}
}
步骤2 把不重复的部分加入新数组nums1
int[] nums1=new int[len];//创建一个新数组存储没有重复值的数组
for(int i=0;i<len;i++){
nums1[i]=nums[i];//给新数组赋值
}
步骤3 nums1排序后就可以考虑两个情况下的返回值了
import java.util.Arrays先引用数组类
Arrays.sort(nums1)给nums1排序
//分情况返回
if(len>=3){//至少有三个不同的数的情况
return nums1[len-3];//注意排序是从小到大的正序
}else{//两个或两个以下的数的情况
return nums1[len-1];
}
由于这个方法中去重部分有两重循环,时间复杂度为O(n²),所以想对方法进行改进,看到同学的方法便学习了一下,以下是第二种解法。
解法2
以下是我对着代码的个人理解,不一定理解的正确,还请见谅,欢迎指正。
import java.util.TreeSet;
用Treeset二叉树的原理对新add()对象进行排序,默认构造方法是从小到大排序, 也能传入Comparator比较器。
Integer和String对象都可以进行默认的TreeSet排序,
TreeSet<Integer> set = new TreeSet<Integer>();
本例中只用对其中的Integer对象进行排序,当加到四个对象的时候把第一个移除。
for (int i = 0; i < nums.length; i++) {
set.add(nums[i]);//对新add()对象进行从小到大排序
if (set.size() > 3) {// 每当窗口扩张到4个时,将最小的清除
set.remove(set.first());//移除第一个最小的数值
}
}
循环后全部加过排序并移除后排断Treeset的大小即对象数有没有3,有刚返回第一个,因为第一个是最小的,没有就返回最后一个。
return set.size() == 3 ? set.first() : set.last();
3.代码实现
解法1
import java.util.Arrays;
public class Main {
public static int solution(int n, int[] nums) {
// write code here
int len=n;
for(int i=0;i<len;i++){
for(int j=i+1;j<len;j++){
if (nums[i]==nums[j]){
nums[j]=nums[len-1];
len--;
j--;
}
}
}
int[] nums1=new int[len];
for(int i=0;i<len;i++){
nums1[i]=nums[i];
}
Arrays.sort(nums1);
if(len>=3){
return nums1[len-3];
}else{
return nums1[len-1];
}
}
public static void main(String[] args) {
System.out.println(solution(12, new int[]{7,12,11,5,6,9,11,13,2,9,12,12}) );
}
}
解法2
import java.util.TreeSet;
public class Main {
public static int solution(int n,int[] nums) {
TreeSet<Integer> set = new TreeSet<Integer>();
for (int i = 0; i < nums.length; i++) {
set.add(nums[i]);// 每当窗口扩张到4个时,将最小的清除
if (set.size() > 3) {
set.remove(set.first());
}
}
return set.size() == 3 ? set.first() : set.last();
}
public static void main(String[] args) {
System.out.println(solution(3,new int[] { 3, 2, 1 }));
System.out.println(solution(2,new int[] { 1, 2 }));
System.out.println(solution(9,new int[] { 2, 5, 4, 6, 2, 3, 7, 8, 1 }));
}
}
4.总结
以上就是我对这道题的思路和改进,有更好的方法希望可以指教指教一起学习,谢谢你观看到这里,祝大家刷题顺利。