Leetcode937 Reorder Data in Log Files
原文地址
有一系列logs, 每条log由以空格分开的若干单词组成, 第一个单词为标识符, 后面的为正文, 通过正文可以将log分为两类, 字母log和数字log
要求排序, 字母log必须在数字log前, 字母log间按照log正文的字典序排序, 如果正文相同则按标识符排序, 数字log直接保持原序
题目已经很明显的告诉我们这是一个自定义排序题了
下面有三个实现方法, 其中两个使用了lambda匿名函数, 还有一个实现了自定义Comparator
解法一 lambda+空格分离
使用lambda匿名函数, 但是分解标识符和正文的方法比较愚蠢, 方法是找到第一个空格从而分开
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public String[] reorderLogFiles(String[] logs) { Arrays.sort(logs, (log1, log2) -> { int idxOfFirstChar1 = log1.indexOf(' ') + 1; int idxOfFirstChar2 = log2.indexOf(' ') + 1; boolean isDigit1 = Character.isDigit(log1.charAt(idxOfFirstChar1)); boolean isDigit2 = Character.isDigit(log2.charAt(idxOfFirstChar2)); if (!isDigit1 && !isDigit2) { String log1WithoutId = log1.substring(idxOfFirstChar1); String log2WithoutId = log2.substring(idxOfFirstChar2); int cmp = log1WithoutId.compareTo(log2WithoutId); if (cmp != 0) return cmp; else return log1.substring(0, idxOfFirstChar1-1).compareTo(log2.substring(0, idxOfFirstChar2-1)); } else return isDigit1 ? (isDigit2 ? 0: 1) : -1; }); return logs; }
|
解法二 lambda+split
可以使用split
方法配合limit
参数分解正文和标识符
split(regex, limit)
表示对regex模式仅匹配limit-1次, 也即最终得到的数组长度最多为limit
比如本题标识符和正文之间由1个空格分开, 那么使用split(" ", 2)
表示仅匹配空格1次, 分离成包含两个元素的数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public String[] reorderLogFiles(String[] logs) { Arrays.sort(logs, (log1, log2) -> { String[] split1 = log1.split(" ", 2); String[] split2 = log2.split(" ", 2); boolean isDigit1 = Character.isDigit(split1[1].charAt(0)); boolean isDigit2 = Character.isDigit(split2[1].charAt(0)); if (!isDigit1 && !isDigit2) { int cmp = split1[1].compareTo(split2[1]); if (cmp != 0) return cmp; return split1[0].compareTo(split2[0]); } return isDigit1 ? (isDigit2 ? 0 : 1) : -1; }); return logs; }
|
解法三 自定义Comparator
创建一个新的Comparator并且重写compare方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public String[] reorderLogFiles(String[] logs) { Comparator<String> myComparator = new Comparator<String>() { @Override public int compare(String log1, String log2) { String[] split1 = log1.split(" ", 2); String[] split2 = log2.split(" ", 2); boolean isDigit1 = Character.isDigit(split1[1].charAt(0)); boolean isDigit2 = Character.isDigit(split2[1].charAt(0)); if (!isDigit1 && !isDigit2) { int cmp = split1[1].compareTo(split2[1]); if (cmp != 0) return cmp; return split1[0].compareTo(split2[0]); } return isDigit1 ? (isDigit2 ? 0 : 1) : -1; } }; Arrays.sort(logs, myComparator); return logs; }
|
Key Points
- 熟悉lambda语法
() -> {}
- split用法, limit参数的含义
- compareTo方法返回的是0/1/-1, 所以不能直接放入判断语句(与c++不同)