LeetCode 刷题 28

文章介绍了KMP算法在解决字符串匹配问题中的应用,通过使用双指针方法和构建前缀表(next数组)来提高效率,当匹配失败时,可以避免重复匹配已匹配的部分。KMP算法的核心是避免回溯,利用已知的匹配信息来决定模式串的下一个匹配位置。
摘要由CSDN通过智能技术生成

这一题 第一反应是 用map 或者栈

但是仔细想想后觉得太麻烦了

于是选用了双指针的方法

class Solution {
public:
    int strStr(string haystack, string needle) {
        int hay = 0;
        int nee = 0;
        int ans = -1;

        for (; hay < haystack.size(); ++hay)
        {
            if (haystack[hay] == needle[nee])
            {   
                int tem = hay;
                for (; nee < needle.size(); ++nee)
                {
                    if (haystack[hay++] != needle[nee])
                    {
                        nee = 0;
                        hay = tem;
                        break;
                    }
                    
                    if (nee == needle.size() - 1)
                        ans = tem;
                }
            }
        }
        return ans == -1 ? -1 : ans;
    }
};

代码随想录中讲到了 KMP 学习一下

  1. KMP有什么用:KMP的主要思想是出现字符串不匹配时,可以知道一部分已经匹配的内容,避免再次匹配

  1. 什么是前缀表:前缀表是用来回退的,记录了模式串与字符串不匹配时,应该从哪里开始重新匹配模式串

记录下标i之前(包括i)的字符串中,有多大长度的相同前缀后缀。

  1. 为什么要使用前缀表: 找到最长相等的前缀和后缀后, 匹配不同的位置是后缀的后面, 那我们找到前缀之后的位置进行重新匹配就好了 因为 前缀和后缀是一样的啊

  1. 如何计算前缀表:下标i之前(包括i) 有多少个长度相同的前缀后缀

  1. 找到不匹配的位置后, 应该查前一个元素的前缀表, 移动到指定的索引处

  1. next数组:可以是前缀表 也可以是前缀表统一减1 影响的是代码怎么写

  1. 构造next数组(计算前缀表):

void getNext(int *next, const string &s)
{
}
  • 初始化

int j = 0;
next[0] = 0;

定义指针j 指向前缀末尾 next进行赋值 next[i] 表示i(包括i)之前最长相等的前后缀长度

  • 当前缀和后缀不同的情况

个人理解 再把他们看作一种比较, 只要不同就回退到前一位的next对应处

while(j > 0 && s[j] != s[i]
{
    j = next[j - 1];
}
  • 当前后缀相同的情况

if (s[j] == s[i]
{
    ++j;
    next[i] = j;
}

完整代码

void getNext(int *next, string &s)
    {
        int j = 0;
        next[0] = 0;

        for (int i = 1; i < s.size();++i)
        {
            while (j > 0 && s[j] != s[i])
                j = next[j - 1];

            if (s[j] == s[i])
                ++j;

            next[i] = j;
        }
    }

运用上述代码 完成题目

int strStr(string haystack, string needle) {
        int next[needle.size()];

        getNext(next, needle);

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

            if (haystack[i] == needle[j])
                ++j;

            if (j == needle.size())
                return (i - needle.size() + 1);
        }

        return -1;
    }

KMP还是比较难理解的 虽然现在能写出来了 不代表 过几天还会 过段时间再回头重做····

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值