LeetCode-28 实现strStr() KMP算法的学习

简介: LeetCode-28 实现strStr() KMP算法的学习

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/repeated-string-match

题目描述

给定两个字符串 a 和 b,寻找重复叠加字符串 a 的最小次数,使得字符串 b 成为叠加后的字符串 a 的子串,如果不存在则返回 -1。

注意:字符串 "abc" 重复叠加 0 次是 "",重复叠加 1 次是 "abc",重复叠加 2 次是 "abcabc"。

示例 1:
输入:a = "abcd", b = "cdabcdab"
输出:3
解释:a 重复叠加三遍后为 "abcdabcdabcd", 此时 b 是其子串。
示例 2:
输入:a = "a", b = "aa"
输出:2
示例 3:
输入:a = "a", b = "a"
输出:1
示例 4:
输入:a = "abc", b = "wxyz"
输出:-1

解题思路

对于这种问题,暴力法也叫朴素求解法是将两个字符串一个一个比较,可以肯定复杂度为O(mn),但是通过KMP算法,可以将复杂度下降到O(m+n).

KMP算法的原理是,在匹配过程中,匹配字符串之中会有重复的字符,遍历过后如果使用朴素算法,会有多次的遍历,可以使用一个next数组,将有相同前缀的标记起来,在遍历的时候便可以跳过遍历前缀的过程,大大提高了解题效率

next数组构建过程如下:(借用宫水三叶大佬的两张图)

 

 

 


 

 

 

这样,在两个字符串比较过程中,如果发现字符比较不相同,可以直接跳到与当前字符串有相同前缀的字符上,不需要从头开始进行计算。

代码展示

class Solution {
public:
    int strStr(string haystack, string needle) {
        int m = haystack.size();
        int n = needle.size();
        if(n == 0) return 0;
        int iRet = 0;
        vector<int> viNext(n, 0);
        for(int i = 1, j = 0; i < n; i++)
        {
            while(needle[i] != needle[j] && j > 0)
            {
                j = viNext[j - 1];
            }
            if(needle[i] != needle[j])
            {
                viNext[i] = 0;
            }
            else
            {
                viNext[i] = j + 1;
                j++;
            }
        }
        for(int i = 0, j = 0; i < m; i++)
        {
            while(haystack[i] != needle[j] && j > 0)
            {
                j = viNext[j - 1];
            }
            if(haystack[i] != needle[j])
            {
                j = 0;
            }
            else
            {
                j++;
            }
            if(j == n)
            {
                return i - n + 1;
            }
        }
        return -1;
    }
};

运行结果

 

相关文章
|
2月前
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
43 0
|
1月前
|
存储 算法 Java
leetcode算法题-有效的括号(简单)
【11月更文挑战第5天】本文介绍了 LeetCode 上“有效的括号”这道题的解法。题目要求判断一个只包含括号字符的字符串是否有效。有效字符串需满足左括号必须用相同类型的右括号闭合,并且左括号必须以正确的顺序闭合。解题思路是使用栈数据结构,遍历字符串时将左括号压入栈中,遇到右括号时检查栈顶元素是否匹配。最后根据栈是否为空来判断字符串中的括号是否有效。示例代码包括 Python 和 Java 版本。
|
2月前
|
算法
每日一道算法题(Leetcode 20)
每日一道算法题(Leetcode 20)
29 2
|
2月前
【LeetCode 21】28. 实现 strStr()
【LeetCode 21】28. 实现 strStr()
37 0
|
2月前
|
算法
第四章 KMP算法理论基础
第四章 KMP算法理论基础
22 0
|
4月前
|
算法
测试工程师的技能升级:LeetCode算法挑战与职业成长
这篇文章通过作者亲身体验LeetCode算法题的过程,探讨了测试工程师学习算法的重要性,并强调了算法技能对于测试职业成长的必要性。
80 1
测试工程师的技能升级:LeetCode算法挑战与职业成长
|
2月前
|
算法
KMP算法
KMP算法
39 0
|
4月前
|
算法 C++
A : DS串应用–KMP算法
这篇文章提供了KMP算法的C++实现,包括计算模式串的next数组和在主串中查找模式串位置的函数,用于演示KMP算法的基本应用。
|
4月前
|
算法
KMP算法
KMP算法
37 0
|
3月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行