力扣28(java)-实现 strStr()(简单)
题目:
实现 strStr() 函数。
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。
说明:
当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。
示例 1:
输入:haystack = "hello", needle = "ll"
输出:2
示例 2:
输入:haystack = "aaaaa", needle = "bba"
输出:-1
提示:
1 <= haystack.length, needle.length <= 104
haystack 和 needle 仅由小写英文字符组成
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/implement-strstr
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
一、暴力解法
循环依次匹配的子字符串,匹配成功,返回本次匹配的原串的起始点,匹配不成功则原串从下一个字符开始与子串进行匹配。
代码:
二、KMP算法
使用KMP算法:当出现字符串不匹配时,可以知道一部分之前已经匹配的字符串,避免从头开始匹配。
最重要的核心是求next数组的值,称为前缀表,记录下标i(包括i)的字符串中,有多大长度相等的前缀和后缀。
代码:
1 class Solution { 2 public int strStr(String haystack, String needle) { 3 int n = haystack.length(), m = needle.length(); 4 int[] next = new int[m]; 5 //构造前缀表next 6 getNext(next, needle); 7 int j = 0; 8 for(int i = 0; i < n; i++){ 9 while(j > 0 && haystack.charAt(i) != needle.charAt(j)){ 10 j = next[j-1]; 11 } 12 if(haystack.charAt(i) == needle.charAt(j)){ 13 j++; 14 } 15 if(j == needle.length()){ 16 return i - needle.length() + 1; 17 } 18 } 19 return -1; 20 } 21 //具体获取next数组 22 public void getNext(int[] next, String s){ 23 //初始化 24 //j代表前缀末尾 25 int j = 0; 26 //第一个位置的公共前缀长度为0 27 next[0] = 0; 28 for(int i = 1; i < s.length(); i++){ 29 //循环回退 30 while(j > 0 && s.charAt(i) != s.charAt(j)){ 31 j = next[j-1]; 32 } 33 if(s.charAt(i) == s.charAt(j)){ 34 j++; 35 } 36 next[i] = j; 37 } 38 } 39 }
KMP算法看起来很好理解,但实际对于我这个菜鸟来说有点难,后续会整理关于KMP算法的相关知识点,整理好会附带链接~
链接:点这里跳转 【更推荐代码随想录的讲解】:点这里跳转代码随想录文字版解释 && 视频版