代码随想录算法训练营第九天(字符串)| 28. 实现 strStr(),459.重复的子字符串
28. 实现 strStr()
因为KMP算法很难,大家别奢求 一次就把kmp全理解了,大家刚学KMP一定会有各种各样的疑问,先留着,别期望立刻啃明白,第一遍了解大概思路,二刷的时候,再看KMP会 好懂很多。
或者说大家可以放弃一刷可以不看KMP,今天来回顾一下之前的算法题目就可以。
因为大家 算法能力还没到,细扣 很难的算法,会把自己绕进去,就算别人给解释,只会激发出更多的问题和疑惑。所以大家先了解大体过程,知道这么回事, 等自己有 算法基础和思维了,在看多看几遍视频,慢慢就理解了。
题目链接/文章讲解/视频讲解:
看到题目的第一想法:
看到题目只知道要用KMP算法,但是KMP算法不知道怎么写,只能直接看卡哥怎么说的了。
package com.second.day9;
public class StrStr_28 {
/**
* 经典KMP算法题
* @param haystack
* @param needle
* @return
*/
public int strStr(String haystack, String needle) {
if(needle.length() == 0 || haystack.length() == 0)
return -1;
//构建一个next数组
int[] next = new int[needle.length()];
getNext(next, needle);
int j = 0;
for(int i = 0; i < haystack.length(); i++) {
//文本串与模式串不匹配时
while(j > 0 && haystack.charAt(i) != needle.charAt(j)) {
j = next[j - 1];
}
//文本串与模式串匹配时
if(haystack.charAt(i) == needle.charAt(j)) {
j++;
}
//返回结果
if(j == needle.length()) {
return i - j + 1;
}
}
return -1;
}
//构建next数组
public void getNext(int[] next, String needle) {
//初始化
int j = 0; //j代表前缀的长度
next[0] = 0;
//i代表needle还未匹配的位置
for(int i = 1; i < needle.length(); i++) {
//前后缀不相等的情况
while(j > 0 && needle.charAt(j) != needle.charAt(i)) {
j = next[j - 1];
}
//前后缀相等的情况
if(needle.charAt(j) == needle.charAt(i))
j++;
//对next数组赋值
next[i] = j;
}
}
public static void main(String[] args) {
StrStr_28 demo = new StrStr_28();
System.out.println(demo.strStr("mississippi", "issip"));
}
}
看完代码随想录之后的想法:
KMP算法很精妙,咱这种普通人还是需要都看几遍,今天看完这遍,之后写代码的时候还是会忘记的,需要多加练习与巩固。
自己实现过程中遇到哪些困难:
困难可太多了
459.重复的子字符串
本题算是KMP算法的一个应用,不过 对KMP了解不够熟练的话,理解本题就难很多。
我的建议是 KMP和本题,一刷的时候 ,可以适当放过,了解怎么回事就行,二刷的时候再来硬啃
题目链接/文章讲解/视频讲解:
看到题目的第一想法:
无从下手
看完代码随想录之后的想法:
看题解没看明白,看代码,题解大概意思就是,构建一个next数组,如果该字符串可以由重复的子字符串构成的话
return next[next.length - 1] != 0 && s.length() % (s.length() - next[next.length - 1]) == 0;
package com.second.day9;
public class repeatedSubstringPattern_459 {
public boolean repeatedSubstringPattern(String s) {
int[] next = new int[s.length()];
getNext(next, s);
return next[next.length - 1] != 0 && s.length() % (s.length() - next[next.length - 1]) == 0;
}
public void getNext(int[] next, String needle) {
//next数组初始化
int j = 0;
next[0] = j;
for(int i = 1; i < needle.length(); i++) {
//前后缀不相等
while(j > 0 && needle.charAt(i) != needle.charAt(j))
j = next[j - 1];
//前后缀相等
if(needle.charAt(i) == needle.charAt(j))
j++;
//对next数组赋值
next[i] = j;
}
}
}
自己实现过程中遇到哪些困难:
理解思想后,直到next数组怎么写,写代码的过程没什么困难。
想法:
在成为优秀的人的路上,太多东西需要考验了。