28. 实现 strStr()
第一个没有用改进的next。第二个用了。
改进的next没有快多少,可能是因为样例不够充分。
改进的next只需要改动一两句。在原来应该更新next[]的时候“多看了一下后面”的情况,根据这个情况来更新。
这道题标为简单估计是因为暴力也能过?如果这能用KMP应该是困难吧。
class Solution {
//kmp?是简单?
//kmp复习
//next数组是不是有点动态规划的思想?
//dp[i]=next[i],状态定义为,p[0,i)自匹配的前后缀最大长度
//next[0]=-1;
//状态转移:if p[j]=p[next[j]] next[j+1]=next[j+1];
// if p[j]!=p[next[j]] 找自匹配的最大长度--不好写
//为方便循环,t表示p[0,t)的自匹配的前后缀最大长度。
//子问题进行到j+1--应该更新next[j+1]时。初始t=next[j]
//if p[j]=p[t],next[j+1]=t+1;
//if p[j]!=p[t],t=next[t]继续找
public int strStr(String haystack, String needle) {
if(needle.equals(""))return 0;
if(haystack.equals(""))return -1;
char[] hh=haystack.toCharArray();
char[] nn=needle.toCharArray();
int m=hh.length;
int n=nn.length;
int[] next=new int[n];
next[0]=-1;
int j=0;
int t=-1;
//不用for是因为不是每次都会前进一步--当 p[j]!=p[next[j]] 不会前进
//访问p[j]意味着要更新next[j+1]。如果j=p.length-1就麻烦了
while(j<n-1){
if(t<0||nn[j]==nn[t])//写这个只要想最一般的情况。t<0是唯一需要记忆的启动点
next[++j]=++t;
else//动态规划精髓
t=next[t];
}
int pos1=0,pos2=0;
while(pos1<m&&pos2<n){
if(pos2<0||hh[pos1]==nn[pos2]){//和next数组建立有点像
pos1++;
pos2++;
}
else
pos2=next[pos2];
}
//循环结束时,要么p串已经全部匹配完。此时pos2是p串长度。pos1指向s串中匹配子串的下一个字符。
//pos1-pos2就是要求的起始位置
if(pos2==n)
return pos1-pos2;
//要么p没匹配完,s串已经结束了
return -1;
}
}
class Solution {
//kmp?是简单?
//kmp复习
//next数组是不是有点动态规划的思想?
//dp[i]=next[i],状态定义为,p[0,i)自匹配的前后缀最大长度
//next[0]=-1;
//状态转移:if p[j]=p[next[j]] next[j+1]=next[j+1];
// if p[j]!=p[next[j]] 找自匹配的最大长度--不好写
//为方便循环,t表示p[0,t)的自匹配的前后缀最大长度。
//子问题进行到j+1--应该更新next[j+1]时。初始t=next[j]
//if p[j]=p[t],next[j+1]=t+1;
//if p[j]!=p[t],t=next[t]继续找
public int strStr(String haystack, String needle) {
if(needle.equals(""))return 0;
if(haystack.equals(""))return -1;
char[] hh=haystack.toCharArray();
char[] nn=needle.toCharArray();
int m=hh.length;
int n=nn.length;
int[] next=new int[n];
next[0]=-1;
int j=0;
int t=-1;
//不用for是因为不是每次都会前进一步--当 p[j]!=p[next[j]] 不会前进
//访问p[j]意味着要更新next[j+1]。如果j=p.length-1就麻烦了
while(j<n-1){
if(t<0||nn[j]==nn[t])//写这个只要想最一般的情况。t<0是唯一需要记忆的启动点
{ j++;
t++;
next[j]=(nn[j]==nn[t])?next[t]:t;
}
else//动态规划精髓
t=next[t];
}
int pos1=0,pos2=0;
while(pos1<m&&pos2<n){
if(pos2<0||hh[pos1]==nn[pos2]){//和next数组建立有点像
pos1++;
pos2++;
}
else
pos2=next[pos2];
}
//循环结束时,要么p串已经全部匹配完。此时pos2是p串长度。pos1指向s串中匹配子串的下一个字符。
//pos1-pos2就是要求的起始位置
if(pos2==n)
return pos1-pos2;
//要么p没匹配完,s串已经结束了
return -1;
}
}

浙公网安备 33010602011771号