代码随想录算法训练营day9|字符串day2

题目链接🔗:
28. 实现 strStr()
459.重复的子字符串

28. 实现 strStr()

经典的 KMP,构建一个 next 数组,数组下标的值是根据对应字符串中对应下标字符能构成的后缀字符串和能和以首个字符构成的前缀字符串相同的最长数值。

int next[n];
next[0] = -1;
int i = 1, j = -1;
// 使用减一的前缀表 ,注意比较的是i 和 j + 1
for (i = 1; i < n; i++) {
	while (j >= 0 && s[i] != s[j + 1] ) {
		j = next[j];
	} 
	if (s[i] == s[j + 1] ) {
		j++;
	}
	next[i] = j;
}

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

459.重复的子字符串

同样使用 KMP,做法有两种。
一种是将字符串复制后两个相同的字符串进行拼接,找到一个新的原本的字符串,同时要注意找到的不能是原来的两个字符串中的字符串。
第二种方法是通过 next 数组,得到next 的最后一个元素的最大前后缀重复字符数,用字符串总长度作差,假如这个差可以被字符串整除就说明这个字符串是由重复的子字符串组成的。
注意的是选择使用减一的前缀表需要作差的时候额外减一。

总结

KMP:能理解,但是自己写的时候老是出错,还是老老实实背下来吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值