Leetcode面试经典150题-28.找出字符串第一个匹配项的下标

解法都在代码里,不懂就留言或者私信,比第一题稍微难点

用KMP解这个题简直就像大炮打蚂蚁,但是没办法,现在都是这么卷

java 复制代码
package dataStructure.bigFactory;

public class _28Strstr {
    public static int strStr(String s1, String s2) {
        /**健壮性判断*/
        if(s1 == null || s2 == null) {
            return -1;
        }
        /**你比我还大,我怎么可能在内部找到你*/
        if(s2.length() > s1.length()) {
            return -1;
        }
        /**都转成字符数组*/
        char[] sArr1 = s1.toCharArray();
        char[] sArr2 = s2.toCharArray();
        /**获取s2的next数组,整个kmp的核心*/
        int[] next = generateNextArr(sArr2);
        /**pos1和pos2分别代表s1和s2正在匹配的位置*/
        int pos1 = 0;
        int pos2 = 0;
        /**下面开始匹配的过程*/
        while(pos1 < sArr1.length && pos2 < sArr2.length) {
            if(sArr1[pos1] == sArr2[pos2]) {
                pos1 ++;
                pos2 ++;
            } else if(next[pos2] != -1) {
                /**如果还可以回跳,就回跳(不是0位置)*/
                pos2 = next[pos2];
            } else {
                /**不能回跳的时候,表示0~pos1区间找不到这样的开头*/
                pos1 ++;
                /**这个时候pos2肯定是0*/
            }
        }
        /**出循环有两种可能:1.pos1越界了 2.pos2越界了
         * 如果pos1越界代表死都没匹配上,返回-1,pos2越界表示匹配结束找到了可以返回对应的开始位置
         * 我们把现在的pos1往前sArr2.length个就是开始的位置(因为pos1当前是匹配位置的下一个)*/
        return pos2 == sArr2.length? pos1-sArr2.length : -1;
    }

    public static int[] generateNextArr(char[] s2) {
        if(s2.length == 1) {
            return new int[]{-1};
        }        
/**next数组代表最长的前缀和后缀可以匹配的长度,前缀和后缀都不包含整个字符串*/
        int[] next = new int[s2.length];
        /**这个写死,是我们的规定*/
        next[0] = -1;
        next[1] = 0;
        /**aabaaac*/
        int index = 2;
        //这个变量有两个含义:1.从0到index-1这个子数组前缀串和后缀串的最大匹配长度
        //2.计算index的next的值的时候和index-1位置比较的位置
        int nextPosOfPrevious = 0;
        while(index < s2.length) {
            if(s2[index - 1] == s2[nextPosOfPrevious]) {
                next[index ++] = ++nextPosOfPrevious;
            } else if(next[nextPosOfPrevious] >= 0) {
                nextPosOfPrevious = next[nextPosOfPrevious];
            } else {
                next[index ++] = 0;
            }
        }
        return next;
    }

    public static void main(String[] args) {
        String s1 = "aabcca";
        String s2 = "abc";
        System.out.println(strStr(s1,s2));
    }
}

运行结果

最近确实没时间查到底是字节第几高的题了,稍后补充吧

也许KMP这个大家没太懂,过几天有空了我专门写一下KMP的文章解释一下,到时候还以这个为例子

相关推荐
ankleless6 分钟前
Spring Boot 实战:从项目搭建到部署优化
java·spring boot·后端
野生技术架构师44 分钟前
2025年中高级后端开发Java岗八股文最新开源
java·开发语言
静若繁花_jingjing1 小时前
JVM常量池
java·开发语言·jvm
David爱编程2 小时前
为什么线程不是越多越好?一文讲透上下文切换成本
java·后端
A尘埃2 小时前
Redis在地理空间数据+实时数据分析中的具体应用场景
java·redis
csxin2 小时前
Spring Boot 中如何设置 serializer 的 TimeZone
java·后端
杨过过儿2 小时前
【Task02】:四步构建简单rag(第一章3节)
android·java·数据库
青云交2 小时前
Java 大视界 -- Java 大数据分布式计算在基因测序数据分析与精准医疗中的应用(400)
java·hadoop·spark·分布式计算·基因测序·java 大数据·精准医疗
荔枝爱编程2 小时前
如何在 Docker 容器中使用 Arthas 监控 Java 应用
java·后端·docker
喵手2 小时前
Java中Stream与集合框架的差异:如何通过Stream提升效率!
java·后端·java ee