阿坤老师的独特瓷器(Java详解)

一、题目描述

阿坤老师的独特瓷器(Java详解)_第1张图片

示例:

输入:

5

3 4

5 6

2 5

3 7

6 5

 输出:

3

二、题解

思路分析:

题目要求我们计算出“独特瓷器”的个数,而“独特瓷器”是指对于瓷器A,没有另一个瓷器B,直径和高度都大于A。则当有瓷器的直径和高度都大于A时,A不为“独特瓷器”。因此,最简单的方法是通过循环来遍历这N个瓷器,分别判断其是否为“独特瓷器”。然而,由于其使用了双重for循环,会导致部分测试用例运行超时,而导致测试失败

由于只有当瓷器B的直径和高度都大于A时,A才不能为“独特瓷器”,因此我们可以先按照瓷器的直径d(或是高度h)按照从大到小的规则来对这些瓷器按进行排序,这样,瓷器A前面的所有瓷器直径d都大于或等于瓷器A的直径,而当直径d相同时,我们则按照高度h从小到大排序

为什么要这样排序?

当我们将瓷器以d从大到小进行排序,则表明瓷器A前面的所有瓷器的直径d都大于或等于A的直径d,此时,我们只需要判断瓷器的高度h,假设瓷器A前面的所有瓷器直径d都大于A的d(等于的情况后面会讨论),则瓷器A前面有一个瓷器的h大于A的h,则表明A不是“独特瓷器”,此时我们只需以前面瓷器h的最大值来和A的h进行比较,就可以判断出A是否是“独特瓷器”

为什么当d相同时要以h进行从小到大排序?

当d相同时,若将h更大的瓷器B排在A前面,则瓷器高度的最大值max必定大于A,A被判断为不是“独特瓷器”,然而,A的d与B的d相同,不满足B的d和h都大于A,因此,A是“独特瓷器”。所以,当d相同时,我们要将h较小的瓷器A排在前面,先判断A是否为“独特瓷器”,再判断h较大的瓷器B是否为独特瓷器。

实现步骤:

1. 将这n个瓷器的直径d和高h存放到二维数组中

2. 将瓷器以d按从大到小进行排序,当d相同时,以h从小到大进行排序

如何实现二维数组的排序?

我们可以使用Arrays.sort()来实现二维数组的排序。由于Arrays.sort()只能对一维数组进行排序,而对于二维数组,则需要使用自定义的Comparator

Comparator是一个专用的比较器,当对象不支撑自比较或是自比较函数不能满足需求时,可以使用比较器来完成两个对象之间大小的比较

如何实现Comparator接口?

我们需要以d降序排序,当d相同时,以h升序排序

(1)自定义类

定义类MyComparator继承于Comparator<>,并重写compare方法

class MyComparator implements Comparator{
    @Override
     public int compare(int[] o1, int[] o2) {
        //当直径d相同时,按h升序排序
        if(Integer.compare(o1[0],o2[0]) == 0){
            return Integer.compare(o1[1],o2[1]);
        }else {
            //直径d不同时,以d降序排序
            return Integer.compare(o2[0],o1[0]);
        }
    }
}
Arrays.sort(porcelain,new MyComparator());

(2)匿名内部类

Arrays.sort(porcelain, new Comparator() {
    @Override
    public int compare(int[] o1, int[] o2) {
        //当直径d相同时,按h升序排序
        if(Integer.compare(o1[0],o2[0]) == 0){
            return Integer.compare(o1[1],o2[1]);
        }else {
            //直径d不同时,以d降序排序
            return Integer.compare(o2[0],o1[0]);
        }
    }
});

(3)lambda表达式

Arrays.sort(porcelain, (o1, o2) -> {
    //当直径d相同时,按h升序排序
    if(Integer.compare(o1[0],o2[0]) == 0){
        return Integer.compare(o1[1],o2[1]);
    }else {
        //直径d不同时,以d降序排序
        return Integer.compare(o2[0],o1[0]);
    }
});

3. 定义瓷器的最大高度maxH=0(瓷器的高度不可能为负数),遍历这N个瓷器,判断其是否为“独特瓷器”,统计“独特瓷器”的个数

代码实现:

import java.util.Arrays;
import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        //在此输入您的代码...
        int n = scan.nextInt();
        //将这n个瓷器的直径d和高h存放到二维数组中
        int[][] porcelain = new int[n][2];
        for (int i = 0; i < n; i++) {
            porcelain[i][0] = scan.nextInt();
            porcelain[i][1] = scan.nextInt();
        }

        //排序
        //按照直径d降序排序,若d相同,则按照高度h升序排序
        Arrays.sort(porcelain, (o1, o2) -> {
            //当直径d相同时,按h升序排序
            if(Integer.compare(o1[0],o2[0]) == 0){
                return Integer.compare(o1[1],o2[1]);
            }else {
                //直径d不同时,以d降序排序
                return Integer.compare(o2[0],o1[0]);
            }
        });

        //定义最大高度maxH,遍历这n个瓷器,判断其是否为“独特瓷器”
        int maxH = 0;
        int count = 0;
        for (int i = 0; i < n; i++) {
            if(porcelain[i][1] >= maxH){
                count++;
                maxH = porcelain[i][1];
            }
        }
        //输出独特瓷器的个数
        System.out.println(count);
    }
}

题目来自:

阿坤老师的独特瓷器 - 蓝桥云课 (lanqiao.cn)

你可能感兴趣的:(Java刷题,算法,java,蓝桥杯)