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));
// 字母log按照字典序排序
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));
}
// 字母log一定在数字log前面
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++不同)

最后更新: 2020年06月09日 21:56

原始链接: http://roooooobin.github.io/2020/06/03/Reorder-Data-in-Log-Files-Solution/

× thanks~
打赏二维码