【第43天】sort 的复杂运用 | 对二维数组与结构体实现自定义排序

本文已收录于专栏
《Java入门一百练》

学习指引

  • 序、专栏前言
  • 一、二维排序
  • 二、【例题1】
    • 1、题目描述
    • 2、解题思路
    • 3、模板代码
    • 4、代码解析
  • 三、【例题2】
    • 1、题目描述
    • 2、解题思路
    • 3.模板代码
    • 4.代码解析
  • 四、推荐专栏
  • 五、课后习题

序、专栏前言

   本专栏开启,目的在于帮助大家更好的掌握学习Java,特别是一些Java学习者难以在网上找到系统地算法学习资料帮助自身入门算法,同时对于专栏内的内容有任何疑问都可在文章末尾添加我的微信给你进行一对一的讲解。
   但最最主要的还是需要独立思考,对于本专栏的所有内容,能够进行完全掌握,自己完完全全将代码写过一遍,对于算法入门肯定是没有问题的。
   算法的学习肯定不能缺少总结,这里我推荐大家可以到高校算法社区将学过的知识进行打卡,以此来进行巩固以及复习。
  学好算法的唯一途径那一定是题海战略,大量练习的堆积才能练就一身本领。专栏的任何题目我将会从【题目描述】【解题思路】【模板代码】【代码解析】等四板块进行讲解。

一、二维排序

  一维数组排序的需求很常见,我们上篇文章也已经详细讲解过。但其实二维排序问题,也是很常见的问题,特别是刷题时,很多算法都涉及到二维排序的问题,比如最小生成树的kruskal算法以及优化版最短路dijkstra,虽然dijkstra中使用的是优先队列,但本质还是一个排序比较的区别,我们需要去自定义排序。
  当然想实现自定义排序的做法有很多,下文给大家写的都是代码量最少,最好写的方法,当然也具有一定的局限性。

二、【例题1】

1、题目描述

请你将一些箱子装在 一辆卡车 上。给你一个二维数组 boxTypes ,其中 boxTypes[i] = [numberOfBoxesi, numberOfUnitsPerBoxi]

numberOfBoxesi 是类型 i 的箱子的数量。
numberOfUnitsPerBoxi 是类型 i 每个箱子可以装载的单元数量。
整数 truckSize 表示卡车上可以装载 箱子 的 最大数量 。只要箱子数量不超过 truckSize ,你就可以选择任意箱子装到卡车上。

返回卡车可以装载 单元 的 最大 总数。

2、解题思路

显然从贪心的角度来说,我们会选择装载单元数量更大的箱子,也就需要对numberOfUnitsPerBoxi这一个属性进行排序,然后进行选择。

3、模板代码

class Solution {
   public int maximumUnits(int[][] boxTypes, int truckSize) {
        //重写比较器,让能装单元数多的箱子排在前边
        Arrays.sort(boxTypes,(a,b)->b[1]-a[1]);
        //贪心,先让能装多的箱子上车
        int count = 0;
        for(int[] box : boxTypes){
            if(box[0] < truckSize){
        //0表示箱子数量,1表示箱子里装的单元数
                count += box[0] * box[1];
                truckSize -= box[0];
            }else{
                count += truckSize * box[1];
                return count;
            }
        }
        return count;
    }
}

4、代码解析

(a,b)->b[1]-a[1]这种写法,是Java中lambda表达式的写法,本质上我们这样写其实还是实现了一个函数,本质上是实现了一个比较器,ab只是一个参数名。也就是对于任意相邻的数组,让其下标为1来进行排序,这里我们实现的是一个降序排序,如果想实现升序可以写为a[1]-b[1]

三、【例题2】

1、题目描述

给你一个字符串数组 names ,和一个由 互不相同 的正整数组成的数组 heights 。两个数组的长度均为 n

对于每个下标inames[i]heights[i] 表示第 i 个人的名字和身高。

请按身高 降序 顺序返回对应的名字数组 names

2、解题思路

具有一个String类型和int类型的结构,我们只能使用结构体去进行存储排序

3.模板代码

 public String[] sortPeople(String[] names, int[] heights) {
        int n = names.length;
        Node[] node = new Node[n];
        for (int i = 0; i < n; i++) {
            node[i] = new Node(names[i], heights[i]);
        }
        Arrays.sort(node, Comparator.comparing(a -> a.d));
        int pre = n - 1;
        for (int i = 0; i < n; i++) {
            names[i] = node[pre--].s;
        }
        return names;
    }

     class Node {
        String s;
        int d;

        public Node(String s, int d) {
            this.s = s;
            this.d = d;
        }
    }

4.代码解析

Comparator.comparing(a -> a.d)这个参数,含义是直接指定该结构体以d进行排序,d就是我们结构体的身高属性。对于一个结构体或者二维数组,想指定某个属性进行排序,我们即可以使用这个函数指定。当然如果是想实现复杂的自定义排序时,我们还是选择实现Comparable这个接口,然后重写compareTo比较方法。

public String[] sortPeople(String[] names, int[] heights) {
        int n = names.length;
        Node[] node = new Node[n];
        for (int i = 0; i < n; i++) {
            node[i] = new Node(names[i], heights[i]);
        }
        Arrays.sort(node);
        int pre = n - 1;
        for (int i = 0; i < n; i++) {
            names[i] = node[pre--].s;
        }
        return names;
    }

     class Node implements Comparable<Node> {
        String s;
        int d;
        public Node(String s, int d) {
            this.s = s;
            this.d = d;
        }
         @Override
         public int compareTo(Node o) {
             return d-o.d;
         }
     }

四、推荐专栏

《零基础学算法100天》

五、课后习题

序号 题目链接 难度评级
1 卡车上的最大单元数 1
1 按身高排序 1
学习有疑问?

你可能感兴趣的:(《Java入门100练》,java,算法,数据结构,排序算法)