实现strStr:模式串匹配『java实现』

题目:

实现strStr:模式串匹配『java实现』_第1张图片

解题方法:

  • 看到题目首先想到的是,该题可以使用BF算法
  • KMP算法
  • 还有官方解答的方法

解法一:

BF算法:回溯
思路:

定义两个指针,一个代表主串位置;一个代表子串位置,两两逐一比较,如果不成功,主串指针回溯,比较下一个,子串回0。直到比较完子串的字符,都相等则返回在主串与子串比较的第一个字符相等时的位置。

【代码实现:】

class Solution {
    public int strStr(String haystack, String needle) {
        int i = 0;          //主串标记
        int j = 0;          //子串标记
        while((i<haystack.length())&&(j<needle.length())){
            if(haystack.charAt(i) == needle.charAt(j)){
                i++;
                j++;
            }else{
                i = i-j+1;      //主串指针回溯(比较下一个位置)
                j = 0;          
            }
        }
        if(j>=needle.length()){
            return i-needle.length();
        }else{
            return -1;
        }
    }
}

【测试:】

实现strStr:模式串匹配『java实现』_第2张图片
结果成功!但是,因为主串(haystack)与模式串(needle)前面已有多个字符比较相等时,只要后面有一个字符不相等,则需要将主串的比较位置 i回退,还有模式串位置回0,所以效率非常低,不建议使用

时间复杂度:

O(nm):假设模式串的前m-1个字符序列和主串的相应的字符序列总是相等,而模式串的第m个字符和主串的相应字符总是不相等,此时,模式串的m个字符序列必须和主串相应字符序列块一共比较n-m+1次,每次比较m个字符。总需比较m(n-m+1)次,因此时间复杂度为O(n*m)。

解法二:

KMP算法:不回溯
思路:
参考博客
https://editor.csdn.net/md/?articleId=106177760

【代码实现:】


class Solution {
    public int strStr(String haystack, String needle) {
     int[] next = getNext(needle);    
     int i = 0;                         
     int j = 0;                         
     while( i<haystack.length() && j<needle.length()){
         if(j == -1||haystack.charAt(i) == needle.charAt(j) ){
             i++;
             j++;
         }else{
             j = next[j];
         }
     }
     if(j<needle.length()){
         return -1;
     }else{
         return (i-needle.length());
     }
    }
    public int[] getNext(String T){
        int[] next = new int[T.length()];
        int j = 1;
        int k = 0;
        next[0] = -1;
        next[1] = 0;
        while(j<T.length()-1){
            if(T.charAt(j) == T.charAt(k)){		//匹配
                next[j+1] = k+1;
                j++;
                k++;
            }else if(k == 0){					//失配
                next[j + 1] = 0;
                j++;
            }else{
                k = next[k];
            }
        }
        return (next);
    }
}

【测试结果:】
实现strStr:模式串匹配『java实现』_第3张图片

解法三:官方解答

思路:
实现strStr:模式串匹配『java实现』_第4张图片
实现strStr:模式串匹配『java实现』_第5张图片
实现strStr:模式串匹配『java实现』_第6张图片
实现strStr:模式串匹配『java实现』_第7张图片
实现strStr:模式串匹配『java实现』_第8张图片

【代码实现:】

class Solution {
  public int strStr(String haystack, String needle) {
    int L = needle.length(), n = haystack.length();
    if (L == 0) return 0;

    int pn = 0;
    while (pn < n - L + 1) { //子串第一个字符开始与主串比较时的最大位置长度时的长度
      while (pn < n - L + 1 && haystack.charAt(pn) != needle.charAt(0)) ++pn;//与子串的第一个字符比较,不等直接比叫主串的下一个位置,相等则退出该循环

      int currLen = 0, pL = 0;
      while (pL < L && pn < n && haystack.charAt(pn) == needle.charAt(pL)) {//遇到第一个相等时,继续比较主串与子串的下一个位置。
        ++pn;
        ++pL;
        ++currLen;
      }

      if (currLen == L) return pn - L;//比较完之后返回开始主串与子串第一个字符相等时的位置
      pn = pn - currLen + 1;//比较过程中遇到不相等的,从主串开始比较时的下一个位置再与子串第一个进行比较。
    }
    return -1;
  }
}

【测试:】
实现strStr:模式串匹配『java实现』_第9张图片

时间复杂度:

时间复杂度:最坏时间复杂度为 O((N - L)L)O((N−L)L),最优时间复杂度为 O(N)O(N)。
空间复杂度:O(1)O(1)。

注:此方法与BF算法类似,但是效率有所提高!

你可能感兴趣的:(LeetCode解题报告)