• LeetCode28.找出字符串中第一个匹配项


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

    给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle
    字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。

    示例 1:

    输入:haystack = “sadbutsad”, needle = “sad” 输出:0 解释:“sad” 在下标 0 和 6 处匹配。
    第一个匹配项的下标是 0 ,所以返回 0 。 示例 2:

    输入:haystack = “leetcode”, needle = “leeto” 输出:-1 解释:“leeto” 没有在
    “leetcode” 中出现,所以返回 -1 。

    提示:

    1 <= haystack.length, needle.length <= 104 haystack 和 needle
    仅由小写英文字符组成


    思路 一

    朴素匹配

    顾名思义最简单的匹配方式但是时间复杂度较高

    首先将字符串通过toCharArray函数转为数组

    for循环定义 i 指针指向hayStack数组的起始位置,索引在 [0 ~ (n - m + 1)]内遍历

    嵌套while循环 如果字符匹配则 a ,b 指针继续同时向前

    直到b = m或者 指针指向的内容不相同

    最后返回 i 指针

    class Solution {
        public int strStr(String haystack, String needle) {
            int n = haystack.length();
            int m = needle.length();
            //字符串转成数组
            char[] hay = haystack.toCharArray();
            char[] ned = needle.toCharArray();
    
            for (int i = 0; i <= n - m; i++){
                int a = i, b = 0;
                while (b < m && hay[a] == ned[b]){
                    ++a;
                    ++b;
                }
                //如果能够完全匹配。返回原串的发起点下标
                if(b == m) return i;
    
            }
            return -1;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    思路二

    KMP算法

    没啥好说的,写原理的帖子很多

    当模版背下来就好

    class Solution {
        //KMP算法,源串为 string, 匹配串为pattern
        //不管何时,string的指针不回溯
        //pattern的指针有条件地回溯
        public int strStr(String haystack, String needle) {
            if (needle.length() == 0) return 0;
            int[] next = new int[needle.length()];
            getNext(next, needle);
     
            int j = 0;
            for (int i = 0; i < haystack.length(); i++) {
                while (j > 0 && needle.charAt(j) != haystack.charAt(i)) 
                //j指针回溯
                    j = next[j - 1];
                if (needle.charAt(j) == haystack.charAt(i)) 
                    j++;
                if (j == needle.length()) 
                    return i - needle.length() + 1;
            }
            return -1;
    
        }
        
        //寻找nxet数组
        private void getNext(int[] next, String s) {
            int j = 0;
            next[0] = 0;
            for (int i = 1; i < s.length(); i++) {
                while (j > 0 && s.charAt(j) != s.charAt(i)) 
                //如果 s.charAt(j) 和 s.charAt(i) 不相等,说明当前位置匹配失败,需要回溯到前一个可能匹配的位置,即 j = next[j - 1]。
                    j = next[j - 1];
                 //如果 s.charAt(j) 和 s.charAt(i) 相等,说明找到了一个更长的重复前缀和后缀,将 j 的值增加 1。
                if (s.charAt(j) == s.charAt(i)) 
                    j++;
                //将 j 的最新值赋给 next[i],表示在位置 i 处的字符之前的最长重复前缀和后缀的长度。
                next[i] = j; 
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    NEXT数组演示
    next数组

  • 相关阅读:
    如何安装Docker桌面版到Windows系统上
    <专利>机器人3D视觉快速定位抓取方法及系统
    java源码用到的设计模式
    程序员节的由来
    bmp图片处理
    从零实现深度学习框架——衡量算法的基本指标
    JAVA中Maven是什么
    Flutter实战-请求封装(三)之http2
    【PyTorch深度学习项目实战100例】—— 基于CNN卷积神经网络实现中文手写汉字识别 | 第60例
    SSM便民自行车管理系统毕业设计-附源码191633
  • 原文地址:https://blog.csdn.net/m0_52320920/article/details/136711827