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;
           


    }
}
posted @ 2021-04-26 20:54  wsshub  阅读(39)  评论(0)    收藏  举报