kmp next 数组 中 前缀指针 j 回溯

https://www.bilibili.com/video/BV1jb411V78H/?spm_id_from=333.337.search-card.all.click&vd_source=bde90da16f250a6e50477a7d2d583283

关键:最长相同前后缀

class Solution {
public:
    int strStr(string haystack, string needle) {
        int n = haystack.size(), m = needle.size();
        if (m == 0) {
            return 0;
        }
        vector<int> next(m);
        for (int i = 1, j = 0; i < m; i++) {
						//其中i指向后缀的末尾,j指向前缀的末尾
						// 不匹配,遇见冲突,看前一位的相同前缀的位
						//例子"abcabd abcabd abcaaa"
						//next数组为next:{0, 0, 0, 1, 2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 4, 1}
						//在最后的abca a a中,后缀末尾的a与当前j指向的前缀末尾不匹配,所以前缀j要向前回退
						//如果直接将j退到0,则不是一个好的方法, 可能会忽略掉前面已有的相同前后缀
						//之前的最长相同前缀1为abc abd abc
						//            后缀1         abc abd abc
						//这里面是否也存在某个相同前后缀
						//前后缀是相同的,在前缀中再找到一个相同前后缀即可,就是j移动的位置
						//此时存在abc abd abc存在一个相同前后缀
						//即前缀2 abc
						//  后缀2 abc
						//则前缀1中的前后缀2,也会存在与后缀2中,
						//且前缀的前缀的下一个字符 needle[j]==needle[i]=a,这时的i还指向整个循环的后缀
						
            while (j > 0 && needle[i] != needle[j]) {
                j = next[j - 1];
            }
            if (needle[i] == needle[j]) {
                j++;
            }
            pi[i] = j;
        }
        for (int i = 0, j = 0; i < n; i++) {
            while (j > 0 && haystack[i] != needle[j]) {
                j = next[j - 1];
            }
            if (haystack[i] == needle[j]) {
                j++;
            }
            if (j == m) {
                return i - m + 1;
            }
        }
        return -1;
    }
};


  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值