代码重构:leetcode 28. 实现 strStr()

159 阅读1分钟

28. 实现 strStr()

这可以是一个暴力匹配的简单题。但如果这样写,就显得毫无意义。

于是,可以写KMP算法。

这题的重点是理解KMP算法中的next求解方式,按照之前我们所努力的,给我们的求解问题建模:

设要匹配的串是pattern,设k是pattern[j]匹配失败时该返回的一系列位置,我们保证k是从大到小的,也就是说pattern[j]匹配失败时候,会进行多次重新定位,这一系列的位置是k的取值空间,设集合是kset。

于是我们就可以得到,首先next[0]=-1:

  1. 按照我们的编程模型,k是pattern[j]匹配失败时该返回的一系列位置,于是必是已经求解出来的。
  2. 假设pattern[k]==pattern[j],显然next[j+1]=k+1,画图理解next的定义就能明显看出来。
  3. 假设pattern[k]!=pattern[j],我们的目的是为了求解next[j+1],于是需要找到一个满足步骤2的k值,因为k越大越好,所以取kset里面较小于当前k值的值,于是k=next[k],继续求解

于是就可以书写代码了:

    public int[] getNext(String pattern) {
        int[] next = new int[pattern.length()];
        next[0] = -1;
        int k = -1, j = 0;//k定义为当前j不匹配时候所在的一串位置中的一个,由大到小
        while (j < pattern.length() - 1) {
            if (k == -1 || pattern.charAt(k) == pattern.charAt(j)) {
                next[++j] = ++k;
            } else k = next[k];
        }
        return next;
    }

    public int strStr(String haystack, String needle) {
        if (needle == null || needle.length() == 0) return 0;
        int[] next = getNext(needle);
        int i = 0, j = 0;
        while (i<haystack.length()) {
            if (j==-1||needle.charAt(j)==haystack.charAt(i)){
                ++j;++i;
            }else j=next[j];
            if (j==needle.length()) return i-needle.length();
        }
        return -1;
    }