317. 多关键字排序

在这里插入图片描述

/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
 */

package ahwoj;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;

/**
 * 题目说排序关键字优先级依次降低,那就是说,排序关键字序列中,后面的元素得先排序,否则会被后续排序关键字排序结果覆盖,优先级高的不能被覆盖。
 */
 // 每一行用列表的话,会超时,因为列表内是Integer,有装箱拆箱的过程,有一些大数据量用例就超时了,所以将每行定义成数组,就ok了
public class MutiKeySort317 {  // 大数据量超时
    public static void mutiKeySort(int m, int n, int[] keys, List<ArrayList<Integer>> list) {
        // Collections.sort(list, (o1, o2) -> {
        //     for(int i = 0; i < o1.size(); i++) {
        //         if (o1.get(i) != o2.get(i)) {
        //             return (o1.get(i) - o2.get(i)) * keys[i];
        //         }
        //     }
        //     return 0;
        // });
        // Collections.sort(list, new Comparator<ArrayList<Integer>>() {
        //         @Override
        //         public int compare(ArrayList<Integer> o1, ArrayList<Integer> o2) {
        //             for(int i = 0; i < o1.size(); i++) {
        //                 if (o1.get(i) == o2.get(i)) {
        //                     continue;
        //                 }
        //                 return (o1.get(i) - o2.get(i)) * keys[i];
        //             }
        //             return 0;
        //         }
        //     });
        list.sort(new Comparator<ArrayList<Integer>>() {
            @Override
            public int compare(ArrayList<Integer> o1, ArrayList<Integer> o2) {
                for(int i = 0; i < o1.size(); i++) {
                    if (o1.get(i) == o2.get(i)) {
                        continue;
                    }
                    return (o1.get(i) - o2.get(i)) * keys[i];
                }
                return 0;
            }
        });
    }

    public static void main(String[] args) {
        // 输入list
        Scanner scanner = new Scanner(System.in);
        String[] mn = scanner.nextLine().split(" ");
        int n = Integer.parseInt(mn[0]);
        int m = Integer.parseInt(mn[1]);
        int[] keys = new int[m];
        String[] keysStr = scanner.nextLine().split(" ");
        List<ArrayList<Integer>> list = new ArrayList<>();
        for (int i = 0; i < m; i++) {
            keys[i] = Integer.parseInt(keysStr[i]);
        }
        for (int i = 0; i < n; i++) {
            ArrayList<Integer> array = new ArrayList<>();
            String[] arrayStr = scanner.nextLine().split(" ");
            for (int j = 0; j < m; j++) {
                array.add(Integer.parseInt(arrayStr[j]));
            }
            list.add(array);
        }
        // 排序
        mutiKeySort(m, n, keys, list);
        // 输出
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                System.out.print(list.get(i).get(j));
                if (j != m-1) {
                    System.out.print(" ");
                } else {
                    System.out.println();
                }
            }
        }
    }
}

// ok,通过

/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
 */

package ahwoj;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;

/**
 * 题目说排序关键字优先级依次降低,那就是说,排序关键字序列中,后面的元素得先排序,否则会被后续排序关键字排序结果覆盖,优先级高的不能被覆盖。
 * 每一行用列表的话,会超时,因为列表内是Integer,有装箱拆箱的过程,所以将每行定义成数组,就ok了
 */
public class MutiKeySort317 {
    public static void mutiKeySort(int m, int n, int[] keys, List<int[]> list) {
        list.sort(new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                for(int i = 0; i < o1.length; i++) {
                    if (o1[i] == o2[i]) {
                        continue;
                    }
                    return (o1[i] - o2[i]) * keys[i];
                }
                return 0;
            }
        });
    }

    public static void main(String[] args) {
        // 输入list
        Scanner scanner = new Scanner(System.in);
        String[] mn = scanner.nextLine().split(" ");
        int n = Integer.parseInt(mn[0]);
        int m = Integer.parseInt(mn[1]);
        int[] keys = new int[m];
        String[] keysStr = scanner.nextLine().split(" ");
        List<int[]> list = new ArrayList<>();
        for (int i = 0; i < m; i++) {
            keys[i] = Integer.parseInt(keysStr[i]);
        }
        for (int i = 0; i < n; i++) {
            int[] array = new int[m];
            String[] arrayStr = scanner.nextLine().split(" ");
            for (int j = 0; j < m; j++) {
                array[j] = Integer.parseInt(arrayStr[j]);
            }
            list.add(array);
        }
        // 排序
        mutiKeySort(m, n, keys, list);
        // 输出
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                System.out.print(list.get(i)[j]);
                if (j != m-1) {
                    System.out.print(" ");
                } else {
                    System.out.println();
                }
            }
        }
    }
}

参考:

/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
 */

package kexin;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;

/**
 * 第一行两个整数n,m(m<=10,n<=100000),分别表示有n个需要排序的元素,每个元素有m个排序关键字,优先级依次降低。 第二行m个整数(均为1或-1),每个整数ai表示第i个关键字按升序(1)或是降序排列(-1)。
 * 接下来n行,每行m个整数,表示每个元素的m个关键字。
 *
 * @since 2024-02-18
 */
public class OJ317 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String firstLine = sc.nextLine();
        String[] a1 = firstLine.split(" ");
        int n = Integer.parseInt(a1[0]);
        int m = Integer.parseInt(a1[1]);

        // 排序条件
        String orderLine = sc.nextLine();

        // 普通排序做法
        lsstSort(sc, n, m, orderLine);

        // 优先队列也可以,添加进来就带有顺序,直接输出即可
        queueSort(sc, n, m, orderLine);
    }

    private static void queueSort(Scanner sc, int n, int m, String orderLine) {
        String[] order = orderLine.split(" ");
        // 优先队列和多条件排序是一样的,相当于在添加的时候已经制定顺序,类似插入排序
        Queue<int[]> queue = new PriorityQueue<>(new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                for (int i = 0; i < o1.length; i++) {
                    // 如果相等比较下一个列元素
                    if (o1[i] == o2[i]) {
                        continue;
                    }
                    // o1- o2 直接返回就是默认升序,乘-1就变成逆序
                    return (o1[i] - o2[i]) * Integer.parseInt(order[i]);
                }
                return 0;
            }
        });
        // 添加数据
        while (n > 0) {
            String[] tmp = sc.nextLine().split(" ");
            int[] line = new int[m];
            for (int i = 0; i < m; i++) {
                line[i] = Integer.parseInt(tmp[i]);
            }
            queue.add(line);
            n--;
        }
        while (!queue.isEmpty()) {
            printArray(queue.poll());
        }
    }

    private static void lsstSort(Scanner sc, int n, int m, String orderLine) {
        List<int[]> data = new ArrayList<>();
        while (n > 0) {
            String[] tmp = sc.nextLine().split(" ");
            int[] intArray = new int[m];
            for (int i = 0; i < m; i++) {
                intArray[i] = Integer.parseInt(tmp[i]);
            }
            data.add(intArray);
            n--;
        }

        sort(data, orderLine);
    }

    public static void sort(List<int[]> lsst, String orderLine) {
        String[] order = orderLine.split(" ");
        lsst.sort(new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                for (int i = 0; i < o1.length; i++) {
                    if (o1[i] == o2[i]) {
                        continue;
                    }
                    return (o1[i] - o2[i]) * Integer.parseInt(order[i]);
                }
                return 0;
            }
        });

        for (int[] aa : lsst) {
            printArray(aa);
        }
    }

    private static void printArray(int[] aa) {
        StringBuilder sb = new StringBuilder();
        Arrays.stream(aa).forEach(i -> sb.append(" ").append(i));
        System.out.println(sb.substring(1));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值