LeetCode28.实现strStr()

懒了这么久,重新开始吧。

今天再来看看kmp算法。

题目

实现 strStr() 函数。

给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回  -1

示例 1:

输入: haystack = "hello", needle = "ll"
输出: 2

示例 2:

输入: haystack = "aaaaa", needle = "bba"
输出: -1

说明:

当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。

对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。


分析

其实这道题用java里面haystack.indexOf(needle),一下就可以出来,但是自己kmp总是迷迷糊糊,打算再写一遍。

next函数很重要,求出needle字符串的最大相同的前缀后缀长度,这个长度决定着在haystack和needle比较时遇到不同字母需要偏移多少长度。注意在不满足相同的前缀后缀字母时,k值需要回溯,回溯到上一个最大相同前缀后缀,直到字母相同或者k=-1。

kmp算法让needle与haystack比较,当比较到不同字母时,不一定要重新从头再开始比较,这时候要偏移的位置长度就和next数组中的数有关了。

今天先粗略的记一下,周六日了之后要再详细的回顾一下。

代码

class Solution {
    public int strStr(String haystack, String needle) {
        if((needle.length() == 0 && haystack.length() == 0) || needle.length()==0) return 0;
        int[] next = new int[needle.length()];
        next(needle,next);

        int k = -1;
        for (int i = 0; i < haystack.length(); i++) {
            
            while( k > -1 && needle.charAt(k+1) != haystack.charAt(i) )
                k = next[k];

            if (needle.charAt(k+1) == haystack.charAt(i))
                k ++;

            if (k == needle.length()-1) return i - k ;
        }
        return -1;
    }

    public static void next(String needle, int[] next){
        char[] chars = needle.toCharArray();
        next[0] = -1;
        int k = -1;

        for (int i = 1; i < next.length; i++) {

            while( k != -1 && chars[i] != chars[k+1])
                k = next[k];
            
            if ( chars[i] == chars[k+1])  k = k+1;
            
            next[i] = k;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_38595487/article/details/80699324