代码随想录算法训练营第十天 | 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等

总结

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



目录
相关文章
|
2月前
|
算法
【算法】滑动窗口——找到字符串中所有字母异位词
【算法】滑动窗口——找到字符串中所有字母异位词
|
1月前
|
算法 索引 容器
双指针算法详解
本文介绍了双指针算法及其应用。双指针算法是在数组或字符串中常用的高效技术,通过维护两个指针遍历数据结构以解决特定问题。根据指针移动方向,可分为同向双指针、相向双指针和快慢指针。同向双指针如移动零和复写零问题;快慢指针如快乐数问题;相向双指针如盛水最多的容器、有效三角形数量及多数之和等问题。通过合理运用双指针技巧,可简化代码并提高效率。
34 4
双指针算法详解
|
26天前
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。
|
2月前
|
算法 C++
A : DS串应用–KMP算法
这篇文章提供了KMP算法的C++实现,包括计算模式串的next数组和在主串中查找模式串位置的函数,用于演示KMP算法的基本应用。
|
2月前
|
算法 Java
掌握算法学习之字符串经典用法
文章总结了字符串在算法领域的经典用法,特别是通过双指针法来实现字符串的反转操作,并提供了LeetCode上相关题目的Java代码实现,强调了掌握这些技巧对于提升算法思维的重要性。
|
2月前
|
存储 大数据 测试技术
掌握 GoLang 中的指针:高效代码的提示和技巧
掌握 GoLang 中的指针:高效代码的提示和技巧
|
2月前
|
算法
KMP算法
KMP算法
18 0
|
2月前
|
算法 容器
【算法】双指针
【算法】双指针
|
2月前
|
算法 C++ 容器
【C++算法】双指针
【C++算法】双指针
|
2月前
|
算法 C++
惊爆!KPM算法背后的秘密武器:一行代码揭秘字符串最小周期的终极奥义,让你秒变编程界周期大师!
【8月更文挑战第4天】字符串最小周期问题旨在找出字符串中最短重复子串的长度。KPM(实为KMP,Knuth-Morris-Pratt)算法,虽主要用于字符串匹配,但其生成的前缀函数(next数组)也可用于求解最小周期。核心思想是构建LPS数组,记录模式串中每个位置的最长相等前后缀长度。对于长度为n的字符串S,其最小周期T可通过公式ans = n - LPS[n-1]求得。通过分析周期字符串的特性,可证明该方法的有效性。提供的C++示例代码展示了如何计算给定字符串的最小周期,体现了KPM算法在解决此类问题上的高效性。
53 0
下一篇
无影云桌面