zoukankan      html  css  js  c++  java
  • 【Leetcode】【Easy】Implement strStr()

    Implement strStr().

    Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.

    解题:

    本题为典型的KMP算法考察题,KMP算法描述为:

      设主串S,匹配串P,i为S的索引下标,j为P的索引下标,初始i和j设置为0。

      在i小于S的长度和j小于P的长度时,开始循环:

      1、比较S[i]和P[j]是否相同;

      2、如果相同则i++,j++,返回执行第1步;

      3、如果不同,则计算已匹配成功的P[0]~P[j-1]中,相同前缀和后缀的最大长度,设为n;

      4、令i不变,j为n(指向相同前后缀的后一个字符),返回执行第1步;

      循环结束时,查看j值是否等于P的长度,如果等于则匹配成功,否则主串中不包含匹配串。

    计算最长相同前后缀:

      新建一个数组a,数组长度为匹配串P长度。数组的每一位a[i],表示由P[0]~P[i]表示的字符串,最长相同前后缀的位数;

      a[0]初始化为0,令i为1,j为0,对于a[i](0<i<len)有两种情况:

      1、如果P[j] == P[i],那么a[i] = a[i - 1] + 1;

         接着j++,i++重新执行第一步;

      2、当P[j] != P[i],如果j此时为0,表示由P[0]~P[i]组成的字符串没有相同的前缀和后缀,所以a[i]=0,i++继续进行第一步;

      3、当P[j] != P[i],并且j不为0,表示可能包含相同前缀和后缀,则令j = a[j - 1],继续执行第一步;

      直到计算出所有a[i]的值。

    AC代码见:

     1 class Solution {
     2 public:
     3     int strStr(char *haystack, char *needle) {
     4         int num = strlen(needle);
     5         int *next = new int[num];
     6         getNext(needle, next);
     7         
     8         int i = 0;
     9         int j = 0;        
    10         while (haystack[i] != '' && needle[j] != '') {
    11             if (haystack[i] == needle[j]) {
    12                 ++i;
    13                 ++j;
    14             } else if (j == 0) {
    15                 ++i;
    16             } else {
    17                 j = next[j - 1];
    18             }
    19         }
    20         
    21         free(next);
    22         if (needle[j] != '')
    23             return -1;
    24         else
    25             return i - j;
    26     }
    27     
    28     void getNext(char *needle, int *next) {
    29         int i = 1;
    30         int j = 0;
    31         next[0] = 0;
    32         while (needle[i] != '') {
    33             if (needle[i] == needle[j]) {
    34                 next[i] = j + 1;
    35                 ++i;
    36                 ++j;
    37             } else if (j == 0) {
    38                 next[i] = 0;
    39                 ++i;
    40             } else {
    41                 j = next[j - 1];
    42             }
    43         }
    44     }
    45 };
    View Code

    代码优化:

    实际编写中,为了避免判定j是否为0,简化操作。可以设定next数组,取代a数组。next的含义是,当kmp算法需要寻找子串下一个比较的位置时,直接从next数组中取值;

    其中next[0] = -1作为哨兵位,next[i] = a[i - 1],即将a数组整体后移一位保存在next数组中。

    AC代码如下:

     1 class Solution {
     2 public:
     3     int strStr(char *haystack, char *needle) {
     4         int num = strlen(needle);
     5         int *next = new int[num];
     6         getNext(needle, next);
     7         
     8         int i = 0;
     9         int j = 0;        
    10         while (haystack[i] != '' && j < num) {
    11             if (j == -1 || haystack[i] == needle[j]) {
    12                 ++i;
    13                 ++j;
    14             } else {
    15                 j = next[j];
    16             }
    17         }
    18         
    19         free(next);
    20         if (needle[j] != '')
    21             return -1;
    22         else
    23             return i - j;
    24     }
    25     
    26     void getNext(char *needle, int *next) {
    27         int i = 0;
    28         int j = -1;
    29         int strl = strlen(needle);
    30         next[0] = -1;
    31         while (i < strl - 1) {
    32             if (j == -1 || needle[i] == needle[j]) {
    33                 next[++i] = ++j;
    34             } else {
    35                 j = next[j];
    36             }
    37         }
    38     }
    39 };
  • 相关阅读:
    表单提交:button input submit 的区别
    JavaScript中改变this指针的注意事项
    宝塔服务器配置nginx刷新404的问题汇总
    ES6笔记整理
    axios网络请求
    v-model双向绑定
    v-bind动态绑定
    前端模块化
    vue router 路由
    JS高阶函数
  • 原文地址:https://www.cnblogs.com/huxiao-tee/p/4227362.html
Copyright © 2011-2022 走看看