美文网首页
LeetCode 第28题:实现 strStr()

LeetCode 第28题:实现 strStr()

作者: 放开那个BUG | 来源:发表于2021-05-20 16:31 被阅读0次

    1、前言

    题目描述

    2、思路

    这道题虽然简单,但是肯定不能用双层 for 循环来做,所以能想到是使用 kmp 来做。

    但是 kmp 特别不好理解,特别是 next 数组不知道为何而产生,所以我们需要用状态机的方式来理解。KMP算法的主要思想是提前判断如何重新开始查找,而这种判断只取决于模式字符串本身。所以我们需要针对模式串本身构建状态机。后面的查询操作只是根据 txt 串不断的推进状态机的状态更新,只有状态机到了终态,我们才能肯定完全匹配成功。

    3、代码

    public class StrStr {
    
        public int strStr(String haystack, String needle) {
            if(needle == null || needle.length() == 0){
                return 0;
            }
            int M = needle.length();
            int N = haystack.length();
    
            // 构造模式串 needle 的状态机
            // dp[状态][字符] = 下个状态
            int[][] dp = new int[M][256];
    
            // base case
            dp[0][needle.charAt(0)] = 1;
            // 影子状态 X 初始为 0
            int x = 0;
            for(int i = 1; i < M; i++){
                for(int c = 0; c < 256; c++){
                    dp[i][c] = dp[x][c];
                }
                dp[i][needle.charAt(i)] = i + 1;
                // 更新影子状态
                x = dp[x][needle.charAt(i)];
            }
    
            // pat 的初始态为 0
            for(int i = 0, j = 0; i < N; i++){
                // 计算 pat 的下一个状态
                j = dp[j][haystack.charAt(i)];
    
                // 到达终止态,返回结果
                if(j == M){
                    return i - M + 1;
                }
            }
    
            // 没到达终止态,匹配失败
            return -1;
        }
    
        public static void main(String[] args) {
            System.out.println(new StrStr().strStr("", "hh"));
        }
    }
    

    相关文章

      网友评论

          本文标题:LeetCode 第28题:实现 strStr()

          本文链接:https://www.haomeiwen.com/subject/lcqudltx.html