「这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战」
描述
给定一个较长字符串big和一个包含较短字符串的数组smalls,设计一个方法,根据smalls中的每一个较短字符串,对big进行搜索。输出smalls中的字符串在big里出现的所有位置positions,其中positions[i]为smalls[i]出现的所有位置。
- 示例 1:
输入:
big = "mississippi"
smalls = ["is","ppi","hi","sis","i","ssippi"]
输出: [[1,4],[8],[],[3],[1,4,7,10],[5]]
- 示例 2:
输入:
big = "mississippi"
smalls = ["is","ppi","hi","sis","i","ssippi"]
输出: [[1,4],[8],[],[3],[1,4,7,10],[5]]
- 提示:
- 0 <= len(big) <= 1000
- 0 <= len(smalls[i]) <= 1000
- smalls的总字符数不会超过 100000。
- 你可以认为smalls中没有重复字符串。
- 所有出现的字符均为英文小写字母。
解析
根据题意,解法如下:
创建big的线索数组 cube 26,存储每个下一个位置的相同字母位置。 根据 smalls数组中的字符串首字母,简化线索数组初始化次数。
接下来遍历smalls数组,根据 字符串首字母,从 线索数组,遍历以该字母为首的所有位置的可能性。 需要注意的是 短字符串可能为 ""。
class Solution {
public int[][] multiSearch(String big, String[] smalls) {
int first;
int m = smalls.length;
int[] valid = new int[26];
for (int i = 0; i < m; i++){
if (smalls[i].equals("")) continue;
first = (int) smalls[i].charAt(0) - (int) 'a';
if (valid[first] == 0) valid[first] = 1;
}
big =" "+big;
int n = big.length();
int[][] cube = new int[26][n];
for (int i = 0; i <26; i++){
if (valid[i] == 0) continue;
int count = 0;
for (int j = 1;j < n; j++){
int alpha = (int)big.charAt(j) - (int)'a';
if (alpha == i) cube[i][count++] = j;
}
}
int alpha;
int index;
String s;
int[][] results = new int[m][];
for (int i = 0; i < m ; i++){
s = smalls[i];
if (s.equals("")){
results[i]=new int[0];
continue;
}
alpha = (int) s.charAt(0) - (int) 'a';
List<Integer> list = new ArrayList<>();
for (int j = 0; j < n; j++){
index = cube[alpha][j];
if (index <= 0) break;
int k = 0;
while(k < s.length() && index+k < n){
if (big.charAt(index+k) != s.charAt(k)) break;
k++;
}
if (k == s.length()) list.add(index-1);
}
results[i] = Arrays.stream(list.toArray(new Integer[0])).mapToInt(Integer::valueOf).toArray();
}
return results;
}
}
运行结果:
执行结果:通过
执行用时:1457 ms, 在所有 Java 提交中击败了5.30%的用户
内存消耗:48.4 MB, 在所有 Java 提交中击败了78.19%的用户