题目
给定一个较长字符串big
和一个包含较短字符串的数组smalls
,设计一个方法,根据smalls
中的每一个较短字符串,对big
进行搜索。输出smalls
中的字符串在big
里出现的所有位置positions
,其中positions[i]
为smalls[i]
出现的所有位置。
示例:
输入:
big = "mississippi"
smalls = ["is","ppi","hi","sis","i","ssippi"]
输出: [[1,4],[8],[],[3],[1,4,7,10],[5]]
1
2
3
4
2
3
4
提示:
0 <= len(big) <= 1000
0 <= len(smalls[i]) <= 1000
smalls
的总字符数不会超过 100000。- 你可以认为
smalls
中没有重复字符串。 - 所有出现的字符均为英文小写字母。
题解
java
public int[][] multiSearch(String big, String[] smalls) {
int lenBig = big.length(), lenSmall = smalls.length;
// 字符前缀缓存
Map<Character, Set<Integer>> cache = new HashMap<>(26);
for (int i = 0; i < lenBig; i++) {
cache.merge(big.charAt(i), new HashSet<>(Collections.singleton(i)), (o, n) -> {
o.addAll(n);
return o;
});
}
Function<String, int[]> getPositions = s -> {
Set<Integer> indices;
// 字符串为空或者不存在大字符串中不存在以短字符串开头的
if (s.isEmpty() || (indices = cache.getOrDefault(s.charAt(0), new HashSet<>())).isEmpty()) {
return new int[0];
}
int sLen = s.length();
return
indices.stream()
// 是否存在大字符串中
.filter(it -> lenBig - it >= sLen && big.substring(it, it + sLen).equals(s))
.mapToInt(Integer::intValue)
.sorted()
.toArray();
};
// 按照小单词依次遍历
int[][] result = new int[lenSmall][];
for (int i = 0; i < lenSmall; i++) {
result[i] = getPositions.apply(smalls[i]);
}
return result;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35