刷题的日常-重新排列日志文件

96 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第26天,点击查看活动详情

刷题的日常-2022年12月18号

一天一题,保持脑子清爽

重新排列日志文件

来自leetcode的 937 题,题意如下:

给你一个日志数组 logs。每条日志都是以空格分隔的字串,其第一个字为字母与数字混合的 标识符 。

有两种不同类型的日志:

  • 字母日志:除标识符之外,所有字均由小写字母组成
  • 数字日志:除标识符之外,所有字均由数字组成

请按下述规则将日志重新排序:

  • 所有 字母日志 都排在 数字日志 之前。
  • 字母日志 在内容不同时,忽略标识符后,按内容字母顺序排序;在内容相同时,按标识符排序。
  • 数字日志 应该保留原来的相对顺序。 返回日志的最终顺序。

理解题意

通过题意,我们可以将信息整理如下:

  • 题目给出一个字符串数组
  • 要求我们根据规则对数组进行排序
  • 返回排序后的内容

做题思路

我们可以开辟一个优先级队列存储规则数据,从后往前扫描日志,如果是数字日志,直接放进结果集即可,如果是,则放进优先级队列进行排序,最后将所有数据放进结果返回即可,步骤如下:

  • 开辟一个优先级队列并设置排序规则
  • 对数组进行扫描
  • 将数组里的内容放进队列中
  • 将队列中排序好的结果放进数组里
  • 返回结果

代码实现

代码实现如下:

public class Solution {
    public String[] reorderLogFiles(String... logs) {
        int pre = logs.length - 1, post = pre;
        PriorityQueue<String> queue = new PriorityQueue<>((o1, o2) -> {
            String[] s1 = o1.split(" ", 2);
            String[] s2 = o2.split(" ", 2);
            int result = s1[1].compareTo(s2[1]);
            return result == 0 ? s1[0].compareTo(s2[0]) : result;
        });
        String[] tmp;
        String tmpStr;
        while (pre > -1) {
            tmp = logs[pre].split(" ");
            tmpStr = tmp[1];
            char currChar = tmpStr.charAt(0);
            if (currChar >= 'a' && currChar <= 'z') {
                queue.add(logs[pre]);
                pre--;
                continue;
            }
            tmpStr = logs[post];
            logs[post--] = logs[pre];
            logs[pre--] = tmpStr;
        }
        pre = 0;
        while (!queue.isEmpty()) {
            logs[pre++] = queue.poll();
        }
        return logs;
    }
}