力扣:17.17. 多次搜索

145 阅读1分钟

「这是我参与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%的用户