这两题需要巩固!!!
28.实现strStr()
文章链接:代码随想录 (programmercarl.com)
思路:使用KMP算法,因为是要判断子字符串是否在另一个字符串中出现过,KMP算法还需要定义获取子字符串的Next数组
Java代码:
class Solution {
public int strStr(String haystack, String needle) {
//使用KMP算法
int indexhay = 0;
int indexnee = 0;
//计算需要获取needle的next数组
int[] needleNext = getNextarray(needle);
//开始遍历比较
while(indexhay < haystack.length() && indexnee < needle.length()){
//两个字符串字符相等的情况
if(haystack.charAt(indexhay) == needle.charAt(indexnee)){
indexhay++;
indexnee++;
}
//没匹配上的情况如下
//如果此时indexnee大于0,表示可以通过next数组重新定位indexnee
else if(indexnee > 0){
//找到新的indexnee位置在跟indexhay处的字符进行比较
indexnee = needleNext[indexnee];
}
//indexnee比0小了,不能再调用next数组了
else{
indexhay++;
}
}
//如果此时indexnee在遍历完最后一个字符时,再++
return indexnee == needle.length()? indexhay - indexnee : -1;
}
//定义获取next数组的函数
private int[] getNextarray(String s){
if(s.length() == 1){
return new int[] {-1};
}
int[] next = new int[s.length()];
next[0] = -1;//人为规定
next[1] = 0;//人为规定
int i = 2;//所以要从i = 2开始
int cn = 0;//cn代表两个意思
while(i < s.length()){
if(s.charAt(i - 1) == s.charAt(cn)){
next[i] = cn + 1;
i++;
cn++;
}
else if(cn > 0){
cn = next[cn];
}
else{
next[i] = 0;
i++;
}
}
return next;
}
}
459.重复的子字符串
文章链接:代码随想录 (programmercarl.com)
思路:想到了使用移动匹配,但不知道具体操作流程是什么。
看完文章后的反思:
(1)移动匹配:用 s + s,这样组成的字符串中,后面的子串做前串,前后的子串做后串,就一定还能组成一个s;
所以判断字符串s是否由重复子串组成,只要两个s拼接在一起,里面还出现一个s的话,就说明是由重复子串组成;
当然,我们在判断 s + s 拼接的字符串里是否出现一个s的的时候,要刨除 s + s 的首字符和尾字符,这样避免在s+s中搜索出原来的s,我们要搜索的是中间拼接出来的s。
Java移动匹配代码:
class Solution {
public boolean repeatedSubstringPattern(String s) {
if(s.length() == 0 || s.equals("")){
return false;
}
//使用移动匹配的方法
String news = s + s;
StringBuilder sb = new StringBuilder();
//要刨除news的首尾字符,要搜索中间是否出现s
for(int i = 1; i < news.length() - 1;i++){
sb.append(news.charAt(i));
}
//在sb中搜索是否存在s,运用StringBuilder的方法indexOf:返回第一个匹配的索引
return sb.indexOf(s) >= 0 ? true:false;
}
}
算法小白还需继续努力!!!