zoukankan      html  css  js  c++  java
  • LeetCode.937-重新排序日志数组(Reorder Log Files)

    这是悦乐书的第358次更新,第385篇原创

    01 看题和准备

    今天介绍的是LeetCode算法题中Easy级别的第220题(顺位题号是937)。你有一系列日志。每个日志都是以空格分隔的单词串。

    每个日志中的第一个单词是标识符,由字母数字组成。

    字母日志,标识符后面的每个单词只包含小写字母。
    数字日志,标识符后面的每个单词只包含数字。

    每个日志在其标识符后至少有一个单词。

    重新排序日志,以便所有字母日志都在任何数字日志之前。字母日志按字典顺序排序,忽略标识符,在特定的情况下使用标识符。数字日志应按其原始顺序排列。返回日志数组的最终顺序。例如:

    输入:["a1 9 2 3 1", "g1 act car", "zo4 4 7", "ab1 off key dog", "a8 act zoo"]
    输出:["g1 act car", "a8 act zoo", "ab1 off key dog", "a1 9 2 3 1", "zo4 4 7"]

    输入:["a1 9 2 3 1", "g1 act car", "zo4 4 7", "ab1 act car", "a8 act car"]
    输出:["a8 act car", "ab1 act car", "g1 act car", "a1 9 2 3 1", "zo4 4 7"]

    注意

    • 0 <= logs.length <= 100

    • 3 <= logs [i] .length <= 100

    • logs[i]保证有标识符,标识符后面有一个单词。

    02 第一种解法

    题目的意思是给一个字符串数组,每个字符串可以分为字母字符串、数字字符串,按照下面的规则排序:

    • 所有字母字符串排在前,数字字符串排在后。

    • 如果是数字字符串,依旧还按照原来的顺序排。

    而字母字符串的排序规则如下:

    • 字母字符串除去标志位后,按剩下的字符串的字典顺序排序,即小的字母在前,大的字母在后。

    • 如果所有字符串除去标志位后,他们剩下的字符串全都相等,那么就需要按照标志位来排序,标志位也按照字典顺序来排,依旧是小的字母在前,大的字母在后。

    我们可以先将数组中所有的元素区分出来,分别存入两个List中,再对其中只存字母日志的List进行排序,而根据上面这些排序规则,我们可以重写compare方法,通过实现Comparator接口来完成,因为我们使用了List,所以我们排序方法需要使用Collectionssort方法。

    public String[] reorderLogFiles(String[] logs) {
        List<String> list = new ArrayList<String>();
        List<String> list2 = new ArrayList<String>();
        for (String log : logs) {
            String[] tem = log.split(" ");
            if (Character.isLetter(tem[1].charAt(0))) {
                list.add(log);
            } else {
                list2.add(log);
            }
        }
        // 排序
        Comparator<String> com = new Comparator<String>() {
    
            @Override
            public int compare(String o1, String o2) {
                int index = o1.indexOf(' ');
                int index2 = o2.indexOf(' ');
                // 标志位
                String flag = o1.substring(0, index);
                String flag2 = o2.substring(0, index2);
                // 标志位后面的字符串
                String left = o1.substring(index+1);
                String left2 = o2.substring(index2+1);
                // 先比较标志位后面的字符串
                int tem = left.compareTo(left2);
                // 如果标志位后面的字符串都相等,就比较标志位
                return tem == 0 ? flag.compareTo(flag2) : tem ;
            }
    
        };
        Collections.sort(list, com);
        list.addAll(list2);
        return list.toArray(new String[list.size()]);
    }
    

    03 第二种解法

    对于第一种解法,我们也可以直接实现Comparator接口,重写compare方法,思路都是一样的。

    public String[] reorderLogFiles2(String[] logs) {
        Comparator<String> com = new Comparator<String>() {
            @Override
            public int compare(String s, String s2) {
                String[] arr = s.split(" ");
                String[] arr2 = s2.split(" ");
                boolean isDigit = Character.isDigit(arr[1].charAt(0));
                boolean isDigit2 = Character.isDigit(arr2[1].charAt(0));
                // 都是字母
                if (!isDigit && !isDigit2) {
                    int tem = s.substring(s.indexOf(' ')+1).compareTo(s2.substring(s2.indexOf(' ')+1));
                    if (tem == 0) {
                        return arr[0].compareTo(arr2[0]);
                    }
                    return tem;
                }
                return isDigit ? (isDigit2 ? 0 : 1) : -1;
            }
        };
        Arrays.sort(logs, com);
        return logs;
    }
    

    04 小结

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

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

  • 相关阅读:
    mysql5.6.20安装
    唯一识别Windows机器的最佳方法
    不用Root在安卓手机上运行Kali_Linux
    在Windows 7和10上显示上次登录帐户信息
    优化非活动窗口的颜色
    Windows10中以管理员身份打开命令提示符
    在Windows10中更改”WIN+E“快捷键打开目标
    在任务管理器中显示所有CPU内核性能
    Windows启动控制台登录模式
    Fluent Terminal
  • 原文地址:https://www.cnblogs.com/xiaochuan94/p/11049267.html
Copyright © 2011-2022 走看看