代码随想录【Day09】|28. 找出字符串中第一个匹配项的下标、459. 重复的子字符串、《字符串总结》

28. 找出字符串中第一个匹配项的下标

题目链接

题目描述:
实现 strStr() 函数。

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

示例 1: 输入: haystack = “hello”, needle = “ll” 输出: 2

示例 2: 输入: haystack = “aaaaa”, needle = “bba” 输出: -1

说明: 当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。 对于本题而言,当 needle 是空字符串时我们应当返回 0 。

思路:
这题考查KMP算法
需要了解一些概念:

  • KMP名字由来?用来做什么的?
  • 什么是文本串?
  • 什么是模式串?
  • 什么是前缀表?如何构建?

理解前缀和后缀

字符串的前缀
是指不包含最后一个字符的所有以第一个字符开头的连续子串;
字符串的后缀
是指不包含第一个字符的所有以最后一个字符结尾的连续子串。

精髓 —— 找最长相等的 前缀 和 后缀,匹配失败的位置是后缀子串的后面,那么我们找到与其相同的 前缀 的后面重新匹配就可以了!
(前缀表数组中每个位置记录的就是当前子串中最长相等的前后缀长度)

next数组就是前缀表,有的会将数值统一减一,这涉及到具体实现上的习惯。

构造next数组(针对模式串计算):

  1. 初始化
  2. 处理前后缀不相同的情况
  3. 处理前后缀相同的情况

注意下标回退时,可能会连续回退,要保证其next取下标的时候不能越界

动画演示
以模式串aabaaf为例,手撕其对应next数组的构建过程↓
代码随想录【Day09】|28. 找出字符串中第一个匹配项的下标、459. 重复的子字符串、《字符串总结》_第1张图片

难点:
经典KMP,必须掌握。

文本串长度——n,模式串长度——m
时间复杂度:O(n+m)
空间复杂度:O(m)

class Solution {
   
	//构造next数组(针对模式串)
    public void getNext(int[] next, String s) {
   
        int j = -1; //统一减一
        next[0] = j;
        for (int i = 1; i < s.length(); i++) {
   
            while (j >= 0 && s.charAt(i) != s.charAt(j+1)) {
   
                j = next[j]; //回退
            }
            if (s.charAt(i) == s.charAt(j+1)) {
   
                j++; //更新当前子串最长公共前后缀长度
            }
            next[i] = j; //更新next数组
        }
    }
	//字符串模式匹配
    public int strStr(String haystack, String needle) 

你可能感兴趣的:(#,代码随想录,leetcode,算法,java)