【leetcode 28】. 找出字符串中第一个匹配项的下标——一行一行代码解释KMP算法

如果想了解KMP算法,我还写了 一篇 篇幅更大的KMP算法,里面更加详细的推理的KMP算法的理论过程。

【字符串常用算法】——KMP算法(你别闲烦 超详细,给你解释明白) 

function strStr(haystack: string, needle: string): number {
  //获取长度
  const haystackLen = haystack.length,
    needleLen = needle.length;

  // 如果长度相等并且值相等,则直接返回 0,否则返回-1
  if (haystackLen === needleLen) {
    return haystack === needle ? 0 : -1;
  }

  // 根据 模式串的长度创建next数组
  const nextList: number[] = Array(needleLen).fill(0);

  // i 和 j 是模式串的快慢指针,i为快指针,j为慢指针
  // i 用来表示最大后缀,j为最大前缀
  for (let i = 1, j = 0; i < needleLen; i++) {
    // 当模式串的的快慢指针值不相等时,
    // 如果前缀与后缀不相等,则将前缀回退到前一个字符的next值
    // 因为上一个字符的next值已经算出来了,没有必要再对比串更少的字符了
    while (j > 0 && needle[i] !== needle[j]) {
      j = nextList[j - 1];
    }

    //如果两个字符相等,则前缀可以向后移动一个字符
    if (needle[i] === needle[j]) {
      j++;
    }
    //赋值next数组
    nextList[i] = j;
  }

  //其实这步和之前很像,几乎是一样的逻辑
  for (let i = 0, j = 0; i < haystackLen; i++) {
    // 如果前缀与后缀不相等,则将前缀回退到前一个字符的next值
    //此时 j 指向模式串的索引,表示如果该字符匹配失败,则字符串和模式串的哪个字符比较
    while (j > 0 && haystack[i] !== needle[j]) {
      j = nextList[j - 1];
    }

    //前缀与后缀相等,则匹配模式串的下一位
    if (haystack[i] === needle[j]) {
      j++;
    }

    //完成匹配成功
    if (j === needleLen) {
      //返回其开头索引
      return i - needleLen + 1;
    }
  }

  return -1;
}

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值