代码随想录算法训练营第十天 | KMP算法 字符串总结 双指针回顾

简介: 代码随想录算法训练营第十天 | KMP算法 字符串总结 双指针回顾

前言

昨天没有更新训练营第九天内容,是因为昨天的任务是 LeetCode 28. 实现 strStr(),使用 KMP算法进行解答, 关于KMP算法可以查看我之前的文章 从 KMP算法到 Java的 String.indexOf(String str)方法, 今天还是关于 KMP算法的,但是主要是复习,想学习KMP算法相关的可以看我之前的文章

今日任务:

459.重复的子字符串

题目描述

网络异常,图片无法展示
|

思路分析

老规矩 去判断字符串是否为空, 如果为 null就直接返回掉

为字符串新增虚拟头,方便我们后续的操作

然后里面一整个for循环都是用来记录前缀表用的, 具体如下

for (int i = 2, j = 0; i <= len; i++) {
        // 处理元素不一致的情况, 进行后退操作
        while(j > 0 && s.charAt(i) != s.charAt(j + 1)){
            j = next[j];
        }
        // 如果元素一致, 则 j++,表示公共前缀+1
        if (s.charAt(i) == s.charAt(j + 1)){
            j++;
        }
        // 存放当前元素和下标几有公共前缀
        next[i] = j;
    }
复制代码

最后去判断最后一个数的最长公共前缀下标是否大于0, 如果不大于 0就证明这个元素肯定没有公共前缀, 那肯定是错的, 如果大于0之后, 再去计算出公共前缀的长度, 用字符串的长度 % 公共前缀的长度, 如果等于 0,则代表字符串都是由这一个公共前缀重复组成的

这一段不是很好理解,可以去看 代码随想录 或者 我的文章也可以通过 LeetCode里面的代码示例来 debug调试理解

代码展示

public static boolean repeatedSubstringPattern(String s) {
    // 判断当前入参是否为 null
    if (s.length() == 0){
        return false;
    }
    // 获取初始 s的长度
    int len = s.length();
    // 为字符串 s新增虚拟头结点
    s = " " + s;
    // 根据新的字符串生成 公共前缀数组
    int[] next = new int[len+1];
    // 遍历
    for (int i = 2, j = 0; i <= len; i++) {
        // 处理元素不一致的情况, 进行后退操作
        while(j > 0 && s.charAt(i) != s.charAt(j + 1)){
            j = next[j];
        }
        // 如果元素一致, 则 j++,表示公共前缀+1
        if (s.charAt(i) == s.charAt(j + 1)){
            j++;
        }
        // 存放当前元素和下标几有公共前缀
        next[i] = j;
    }
    // 判断是否为一个子串重复构成
    if (next[len] > 0 && len % (len - next[len]) == 0){
        return true;
    }
    return false;
}
复制代码

提交结果

网络异常,图片无法展示
|

字符串总结

什么是字符串

字符串就是由一堆字符组成的有限序列,也可以理解为一个字符数组,毕竟我们遍历字符串的时候通常是转成一个 char[]或者获取指定下标的字符进行操作

// 遍历字符串的常规操作
String str = "abc";
char[] chars = str.toCharArray();
for (int i = 0; i < chars.length; i++) {
    System.out.println(chars[i]);
}
for (int i = 0; i < s.length(); i++) {
    System.out.println(s.charAt(i));
}
复制代码

使用类的已有方法做算法题吗?

除非你了解这个方法的内部实现, 否则是不建议在做算法题的时候直接使用方法的

双指针法

在字符串反转,移除元素,反转单词等题中都有使用到双指针法,在工作中也有真真切切的去使用到,由此可见算法还是要会的,可以不精,但是当工作中碰到难题不至于两眼发懵

同时双指针法的时间复杂度是 O(n)

反转系列

这个感觉相对简单一点,主要就是在细节处理上,这里借用代码随想录的一句话:当需要固定规律一段一段去处理字符串的时候,要想想在在for循环的表达式上做做文章

KMP

KMP 算法就是处理字符串匹配等问题的, 它利用了公共前缀来记录之前匹配过的信息, 能够让我们节省很多时间不用去重复匹配

这个真的很难,很重要, 我第一次看的时候看文字真的一脸懵逼,看了三遍视频,又 debug了一遍才明白

总结

可能是距离上次做字符串部分还不到一个月,这次做起来有种游刃有余的感觉,也可能是因为这次简单题居多的原因吧,等到后面回溯之后估计就开始一脸懵逼了

双指针回顾

双指针法: 是指一快一慢两个指针在同一个 for循环内完成两个 for循环的工作

  • 暴力解法时间复杂度: O(n^2)
  • 双指针时间复杂度: O(n)

关于双指针法比较经典的题有: 反转字符串,判断一个字符串是否为回文字符串,在一个有序数组内判断存不存在两数之和等于target等

总结

一转眼代码随想录训练营已经十天了,十天的进度:数组,链表,哈希表,字符串,按照语句训练营时长两个月一刷还有五十天,坚持就是胜利,日积硅步以致千里



目录
相关文章
|
6天前
|
算法
两个字符串匹配出最长公共子序列算法
本文介绍了最长公共子序列(LCS)问题的算法实现,通过动态规划方法求解两个字符串的最长公共子序列,并提供了具体的编程实现细节和示例。
26 1
两个字符串匹配出最长公共子序列算法
|
2天前
|
存储 搜索推荐 C语言
深入C语言指针,使代码更加灵活(二)
深入C语言指针,使代码更加灵活(二)
|
2天前
|
存储 程序员 编译器
深入C语言指针,使代码更加灵活(一)
深入C语言指针,使代码更加灵活(一)
|
2天前
|
C语言
深入C语言指针,使代码更加灵活(三)
深入C语言指针,使代码更加灵活(三)
深入C语言指针,使代码更加灵活(三)
|
4天前
|
算法
第四章 KMP算法理论基础
第四章 KMP算法理论基础
8 0
|
8天前
|
算法
KMP算法
KMP算法
14 0
|
9天前
|
算法 C++
【算法】双指针+二分(C/C++
【算法】双指针+二分(C/C++
|
1月前
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。
|
2月前
|
算法 C++
A : DS串应用–KMP算法
这篇文章提供了KMP算法的C++实现,包括计算模式串的next数组和在主串中查找模式串位置的函数,用于演示KMP算法的基本应用。
|
8天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于MSER和HOG特征提取的SVM交通标志检测和识别算法matlab仿真
### 算法简介 1. **算法运行效果图预览**:展示算法效果,完整程序运行后无水印。 2. **算法运行软件版本**:Matlab 2017b。 3. **部分核心程序**:完整版代码包含中文注释及操作步骤视频。 4. **算法理论概述**: - **MSER**:用于检测显著区域,提取图像中稳定区域,适用于光照变化下的交通标志检测。 - **HOG特征提取**:通过计算图像小区域的梯度直方图捕捉局部纹理信息,用于物体检测。 - **SVM**:寻找最大化间隔的超平面以分类样本。 整个算法流程图见下图。