码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 【力扣刷题】Day09——字符串专题


    文章目录

      • 5. 找出字符串中第一个匹配项的下标(kmp)
      • 6. 重复的子字符串(kmp)


    上一篇文章:【力扣刷题】Day08——字符串专题_塔塔开!!!的博客-CSDN博客

    5. 找出字符串中第一个匹配项的下标(kmp)

    关于KMP算法的具体解释:

    回顾以前的博客:字符串匹配 - 时间最考验人 - 博客园 (cnblogs.com)

    核心总结:

    • next[j]:存的是模式串s[j]最长相等前后缀的长度,当某一时刻不匹配时j就会跳到next[j](最优),直到找到或者j退无可退(0)
    • KMP匹配的过程和求next[j]是极其相似的

    KMP模板(下标从1开始):

    // s[]是长文本,p[]是模式串,n是s的长度,m是p的长度
    求模式串的Next数组:
    for (int i = 2, j = 0; i <= m; i ++ )
    {
        while (j && p[i] != p[j + 1]) j = ne[j];
        if (p[i] == p[j + 1]) j ++ ;
        ne[i] = j;
    }
    
    // 匹配
    for (int i = 1, j = 0; i <= n; i ++ )
    {
        while (j && s[i] != p[j + 1]) j = ne[j];
        if (s[i] == p[j + 1]) j ++ ;
        if (j == m)
        {
            j = ne[j];
            // 匹配成功后的逻辑
            // cout << i - m << " " // 匹配成功的起始位置
        }
    }
    
    

    题目链接:28. 找出字符串中第一个匹配项的下标 - 力扣(LeetCode)

    思路一:枚举(双指针),模拟,枚举原串 original 中的每个字符作为「发起点」,每次从原串的「发起点」和匹配串的「首位」开始尝试匹配

    Code

    class Solution {
        public int strStr(String haystack, String needle) {
            char[] original = haystack.toCharArray();
            char[] target = needle.toCharArray();
            int n = original.length;
            int m = target.length;
    
            for(int i = 0; i <= n - m; i ++){// n - m:保证原串够目标串进行遍历
                int a = i;
                int b = 0;
                while(b < m && original[a] == target[b]){
                    a ++;
                    b ++;
                }
                if(b == m) return i;
            }
            return -1;
        }
    }
    

    思路二:KMP算法匹配

    Code

    class Solution {
        // ss文本串 pp模式串
        public int strStr(String ss, String pp) {
            if(pp.isEmpty()) return 0;
    
            // 分别读取原串和匹配串的长度
            int n = ss.length(), m = pp.length();
            // 原串和匹配串前面都加空格,使其下标从 1 开始
            ss = " " + ss;
            pp = " " + pp;
    
            char[] s = ss.toCharArray();
            char[] p = pp.toCharArray();
            int[] ne = new int[m + 1];
    
            // 求next[j]
            for(int i = 2, j = 0; i <= m; i ++){
                while(j != 0 && p[i] != p[j + 1]) j = ne[j];
                if(p[i] == p[j + 1]) j ++;
                ne[i] = j;
            }
            
            // 匹配过程
            for(int i = 1, j = 0; i <= n; i ++){
                while(j != 0 && s[i] != p[j + 1]) j = ne[j];
                if(s[i] == p[j + 1]) j ++;
                if(j == m){
                    j = ne[j];
                    return i - m;
                }
            }
            return -1;
        }
    }
    

    6. 重复的子字符串(kmp)

    题目链接:459. 重复的子字符串 - 力扣(LeetCode)

    在由重复子串组成的字符串中,最长相等前后缀不包含的子串就是最小重复子串,这里那字符串s:abababab 来举例,ab就是最小重复单位。

    如果最长的前后缀存在,且整个串的长能够整除最小重复子串的长度,说明改串可以由这个最小重复子串构成!

    Code

    class Solution {
        public boolean repeatedSubstringPattern(String ss) {
            int n = ss.length();
            ss = " " + ss;
            char[] s = ss.toCharArray();
            int[] ne = new int[n + 1];
    		
            // 求next[j]
            for(int i = 2, j = 0; i <= n; i ++){
                while(j != 0 && s[i] != s[j + 1]) j = ne[j];
                if(s[i] == s[j + 1]) j ++;
                ne[i] = j;
            }
    
            
            int len = n;
            int max_fix = ne[len];// 获取最长相等前后缀 长度
            int re_len = len - max_fix;// 获取最小重复串的长度
            if(max_fix != 0 && len % re_len == 0){// 判断整个串是否能被最小重复串覆盖
                return true;
            }
            return false;
        }
    }
    
  • 相关阅读:
    做开发一段时间之后,发现C盘所剩空间越来越少,开发专属的C盘清理命令。
    第一章 信息化和信息系统
    Mac环境下安装Ruby
    新款 锐科达 SV-2702VP SIP广播音频模块 RTP流音频广播
    thinkphp:数据库查询二,嵌套别的表的查询(别的表做子查询)
    自然科学六大基础学科:数学,物理学,化学,生物学,地球科学,天文学
    NLP:自然语言领域NLP模型发展(ELmo→GPT/BERT→MT-DNN→XLNet→RoBERTa→ALBERT)l历程简介、重要算法介绍之详细攻略
    springboot校园疫情智慧防控微信小程序毕业设计源码011133
    [附源码]java毕业设计校园二手交易平台的设计
    Spring底层架构核心概念解析
  • 原文地址:https://blog.csdn.net/qq_54773252/article/details/127113025
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号