
解法:
利用kmp求解,详情见kmp大法。
class Solution {
public int strStr(String haystack, String needle) {
int next[]=new int[needle.length()+1];
getNext(next,needle);//数组是引用数据类型,创建next数组
int i=1,j=1;
while(i<=haystack.length()&&j<=needle.length()){
if(j==0||haystack.charAt(i-1)==needle.charAt(j-1)){
i++;//如果大串和小串是相等的,两个指针继续走
j++;//j等于0就代表和子串开头都不相等,全都++
}else{
j=next[j];//如果不相等子串指针退回到前缀结尾+1的位置
}
if(j>needle.length()){
return i-needle.length()-1;
}
}
return -1;
}
public static void getNext(int[] next,String str){
int i=1,j=0;
next[1]=0;
while(i<str.length()){
if(j==0||str.charAt(i-1)==str.charAt(j-1)){//如果j回溯到0到头了就让他加加到1
i++;
j++;
next[i]=j;//如果i字符和j字符相等,将i+1存入j+1
}else{
j=next[j];//如果i字符和j字符不相等,将j字符倒退到上一个相等前后缀,再去比较
}
}
}
}

解法:
借用了上一题的next数组,由于上一题的next数组是为了方便求解重复字符串的,所以对于这道题来说这样设计next数组其实并非最优解。
想要判断重复的子串,要获取子串的最长前缀剩下的部分,如果剩下的部分是最小单位比如说ab,abc,可以被整体长度整除,那么我们就可以至少知道最后一位剩下的部分是最小单位长度。
同时我们还要判断最后一位是不是符合条件的字符,我们知道这是一个重复子串组合成的串,最后一位如果和子串的末尾不相同的话,其前后缀最大长度必然是0。
以上两个条件同时满足,我们就认为这个字符串是一个重复字符串。
class Solution {
public boolean repeatedSubstringPattern(String s) {
s=" "+s+" ";
int len=s.length();
int[] next=new int[len];
int i=1,j=0;
next[1]=0;
while(i<len-1){
if(j==0||s.charAt(i)==s.charAt(j)){
i++;
j++;
next[i]=j;
}else{
j=next[j];
}
}
if((next[len-1]-1>0)&&(len-2)%((len-2)-next[len-1]+1)==0){
return true;
}
return false;
}
}
文章介绍了如何使用KMP算法来解决字符串查找问题,包括在主串中查找子串以及判断字符串是否由重复子串组成。KMP算法的核心在于构造next数组,用于在不匹配时快速调整子串位置。在第二个解法中,优化了next数组的使用以判断重复子串模式。

被折叠的 条评论
为什么被折叠?



