KMP算法实现思路——附带Leetcode 1392最长快乐前缀和28实现strStr()的KMP解法 Java语言

KMP算法实现思路——附带Leetcode 1392最长快乐前缀和28实现strStr()的KMP解法 Java语言

目标问题

KMP算法主要用于解决字符串匹配相关等问题,实施起来简单,但是过程精巧。

如题在bacbababaabcbab字符串中寻找abababca字符串的位置。一般的思路会是从字符串头开始逐一匹配,再逐一滑动,如果不做任何剪枝,那么会多出很多多余计算。KMP算法即是一种字符串匹配暴力检索的一种剪枝算法。

KMP算法

创建部分匹配表

在进行KMP算法之前,我们首先需要创建一个辅助数组next[],长度为需要寻找的字符串的长度,内容则为从字符串起始点到该索引位置的子字符串([0,..,i])的部分匹配值部分匹配值指该字符串的前缀后缀最长的共有元素的长度(不包含本身)。以下是部分匹配表 数组next[]的样例:

char  a b a b a b c a
index 0 1 2 3 4 5 6 7
value 0 0 1 2 3 4 0 1
- "ab"的前缀有[a],后缀有[b],无匹配,值为0
- "abab"的前缀有[a,ab,aba],后缀有[b,ab,bab],最长匹配的值为ab,值为2

知道了部分匹配表的内容,那么如何创建一个部分匹配表呢?这个问题等同于Leetcode1392题最长快乐前缀

思路如下:

创建长度等同于字符串的数组next[]
for i from 1 to length - 1:
	k = next[i - 1]      //用k记录next[i - 1]即字符串[0-i-1]中最长前后缀匹配的长度
	while(k > 0 && 字符串第k位不等同于第i位):
		k = next[k - 1] // 如果第k位的数等同于第i位的数,那么next[i]就可以等于之前最长前后缀匹配的长度k加上1
					   // 但是如果不等于,next[i]就不是简单的为0,而是应该把k等于字符串[0, k-1]中最长前后缀匹配的长度,这里是因为
					   // 之前已经有k位匹配了,类似于1 2 1 4 1 2 1 2(i),之前已经有1 2 1匹配了,尽管第i位的2不等于4了,但是由于i位前面
					   // 的1 2 1是等同于开头的1 2 1,因此应该寻找1 2 1中的最长前后缀匹配的长度,另其为k。
					   // 如果此时字符串第k位等同于第i位,则中断循环; 如果不等同,则继续重复上面的步骤令k = next[k - 1]
	if 字符串第k位等同于第i位 // 跳出循环要么k = 0了,要么第k位等于第i位了
		next[i] = k + 1 // 等同的情况下,就像上面说的,直接赋值k + 1就行了
	// k = 0的情况且k位不等于i位时,直接默认为0就行了,不需要操作
// 走完for循环,完成匹配表

代码附上Leetcode的1392题的解法:

class Solution {
   
    public String longestPrefix(String s) {
   
        int[] next = new int[s.length()];
        for(int i = 1; i < s.length()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值