LeetCode[28]找出字符串中第一个匹配项的下标(KMP版本)

思路:

一开始我使用暴力过的,但是感觉还是不完美,想学习一下KMP的写法,所以这篇笔记就来了,首先KMP算法就要先维护一个最长相等前后缀的一个数组(统称前缀表),那么这个数组为什么能找出相等字符串呢?因为这个前缀表是维护了当前模式串最长前后缀,一旦出现不相等的情况,就可以根据不相等的位置的前一个位置的下标的值,就是需要回退的次数。

我的理解就是先想KMP算法的时间复杂度,是O(n+m),那么就是一个串遍历一遍,给出的文本串遍历一遍,给出的模式串遍历一遍,所以通过时间复杂度就知道这道题大概的一个for循环的方向,肯定是先遍历模式串算出前缀表,然后再遍历文本串结合前缀表得出答案。其实这个前缀表就在两个字符串中找相等的字符串。

那么说说前缀表怎么算出来的,遍历模式串,然后再来个双指针,初始的时候,头指针指向前缀的头部,尾指针指向后缀的尾部。(注意:前缀-不包含尾指针就是前缀,后缀-不包含尾指针就是后缀)所以尾指针就是初始为1,头指针为0。

前缀表一共三步:

1.头尾指针不相等,那么说明现在前后缀不一样,那么就让头指针向前退一步,直到两个指针相等。

  1. 头尾指针相等的时候,就是说明存在前后缀一样的值了,那么就让头指针往后走一步。

  2. 最后就是更新前缀表的值,遍历模式串的是i,所以next[i] = j,j就代表了当前最长相等的前后缀的个数。

通过拿到的前缀表,我们再对文本串进行遍历,就可以得到当前相等串的第一个下标了,详细的看代码和代码随想录的解释。

代码:

java 复制代码
class Solution {
    public int strStr(String haystack, String needle) {
        if (needle.length() == 0)
            return 0;
        int[] next = new int[needle.length()];
        getNext(next, needle);

        int j = 0;
        for (int i = 0; i < haystack.length(); i++) {
            while (j > 0 && needle.charAt(j) != haystack.charAt(i)) {
                j = next[j - 1];
            }
            if (needle.charAt(j) == haystack.charAt(i)) {
                j++;
            }
            if (j == needle.length()) {
                return i - needle.length() + 1;
            }
        }
        return -1;
    }

    public void getNext(int[] next, String s) {
        int j = 0;
        next[0] = 0;
        for (int i = 1; i < s.length(); i++) {
            while (j > 0 && s.charAt(j) != s.charAt(i)) {
                j = next[j - 1];
            }
            if (s.charAt(j) == s.charAt(i)) {
                j++;
            }
            next[i] = j;
        }
    }
}
相关推荐
一匹电信狗4 小时前
【LeetCode_547_990】并查集的应用——省份数量 + 等式方程的可满足性
c++·算法·leetcode·职场和发展·stl
鱼跃鹰飞5 小时前
Leetcode会员尊享100题:270.最接近的二叉树值
数据结构·算法·leetcode
梵刹古音6 小时前
【C语言】 函数基础与定义
c语言·开发语言·算法
筵陌6 小时前
算法:模拟
算法
We་ct7 小时前
LeetCode 205. 同构字符串:解题思路+代码优化全解析
前端·算法·leetcode·typescript
renhongxia17 小时前
AI算法实战:逻辑回归在风控场景中的应用
人工智能·深度学习·算法·机器学习·信息可视化·语言模型·逻辑回归
CoderCodingNo7 小时前
【GESP】C++四级/五级练习题 luogu-P1223 排队接水
开发语言·c++·算法
民乐团扒谱机7 小时前
【AI笔记】精密光时频传递技术核心内容总结
人工智能·算法·光学频率梳
CoderCodingNo7 小时前
【GESP】C++五级/四级练习题 luogu-P1413 坚果保龄球
开发语言·c++·算法
2301_822366358 小时前
C++中的命令模式变体
开发语言·c++·算法