Leetcode刷题day9|字符串二|28.实现strStr(),459.重复的子字符串,字符串总结,双指针总结

Dear 丶 2024-03-30 15:32 98阅读 0赞

#

文章目录

    • 一、实现strStr()
      • 思路分析
      • 图示分析
      • AC代码
    • 二、重复的子字符串
      • 思路分析
      • 图示分析
      • AC代码
    • 三、字符串总结
      • 什么是字符串
      • 要不要使用库函数
      • 字符串编程题常用算法
        • 双指针法
        • 反转系列
        • KMP算法
    • 四、双指针总结
      • 数组篇
      • 链表篇
      • 字符串篇
      • N数之和

一、实现strStr()

思路分析

图示分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-40fetyPJ-1673002939282)(F:\typora插图\image-20230106160520583.png)]

AC代码

  1. class Solution {
  2. public int strStr(String haystack, String needle) {
  3. int n = haystack.length(), m = needle.length();
  4. if (m == 0) {
  5. return 0;
  6. }
  7. int[] pi = new int[m];
  8. for (int i = 1, j = 0; i < m; i++) {
  9. while (j > 0 && needle.charAt(i) != needle.charAt(j)) {
  10. j = pi[j - 1];
  11. }
  12. if (needle.charAt(i) == needle.charAt(j)) {
  13. j++;
  14. }
  15. pi[i] = j;
  16. }
  17. for (int i = 0, j = 0; i < n; i++) {
  18. while (j > 0 && haystack.charAt(i) != needle.charAt(j)) {
  19. j = pi[j - 1];
  20. }
  21. if (haystack.charAt(i) == needle.charAt(j)) {
  22. j++;
  23. }
  24. if (j == m) {
  25. return i - m + 1;
  26. }
  27. }
  28. return -1;
  29. }
  30. }

二、重复的子字符串

思路分析

图示分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TJ8rmvxg-1673002994091)(F:\typora插图\image-20221128145629476.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IuMWABBq-1673002994092)(F:\typora插图\image-20221128150725440.png)]

AC代码

  1. class Solution {
  2. public boolean repeatedSubstringPattern(String s) {
  3. if (s.equals("")) return false;
  4. int len = s.length();
  5. s = " " + s;
  6. char[] chars = s.toCharArray();
  7. int[] next = new int[len + 1];
  8. for (int i = 2, j = 0; i <= len; i++) {
  9. while (j > 0 && chars[i] != chars[j + 1]) j = next[j];
  10. if (chars[i] == chars[j + 1])
  11. j++;
  12. next[i] = j;
  13. }
  14. if (next[len] > 0 && len % (len - next[len]) == 0) {
  15. return true;
  16. }
  17. return false;
  18. }
  19. }

三、字符串总结

什么是字符串

字符串是由若干字符串组成的有限序列。

C/C++是以’\0’为结尾,java不是。

我们在处理字符串相关问题经常使用chatAt函数或者将字符串通过toCharArray函数转化称为字符数组处理。。

要不要使用库函数

建议:如果题目关键部分可以直接使用库函数解决,就不要使用库函数。

如果库函数只是解题过程中的一小部分,并且我们非常熟悉这个库函数的内部实现原理考虑使用库函数。

另外,在没事的时候,去看看常用字符串函数的实现,分析一下时间复杂度,有个大概印象。

字符串编程题常用算法

常见的问题有字符串查找、字符串反转等。

双指针法

双指针不隶属于任意一种数据结构,数组、链表、字符串中都有所使用

我们这里只说双指针在字符串编程题中的常见用法,至于其他的,我们再单独总结。

比如,在反转字符串中,我们使用了双指针,一首一尾,原地修改了完成了反转;

再比如,在替换空格中,我们使用了双指针,一新一旧(扩容后和扩容前),原地修改字符串完成了要求。

反转系列

对于字符串而言,反转不是一个问题,而是一类问题,在基本的问题上可以衍生出来一些类的问题。虽然这里我把它列到常用算法里了,但其实它并不能算是真正意义上的算法,只是我认为它出题的频率很高,我们可以把这个套路记住,当成一个模板而已。

比如,最基础的反转整个字符串,就是使用双指针,一首一尾将转成字符数组的字符串原地修改。

再比如,分组进行反转,我们的思路就时分组+反转,也就是在原来的基础上套上一个for循环,然后每次的Left和right的值进行特殊化处理,我们这里可以记住之前处理方式,一个就是i,另一个是选数组最大坐标和按照指定分组规则得到的下一组的right坐标,同时for循环每次的修改都是i+=2*k。

总的来说,字符串的翻转系列相较于链表的翻转系列还是比较简单的。

KMP算法

KMP的主要思想是当出现字符串不匹配时,可以知道一部分之前已经匹配的文本内容,可以利用这些信息避免从头再去做匹配了。

KMP的精髓所在就是前缀表,我们必须要弄清楚什么是KMP,什么是前缀表,以及为什么要用前缀表。

那么使用KMP可以解决两类经典问题:

  1. 匹配问题
  2. 重复子串问题

再一次强调了什么是前缀,什么是后缀,什么又是最长相等前后缀。

前缀:指不包含最后一个字符的所有以第一个字符开头的连续子串。

后缀:指不包含第一个字符的所有以最后一个字符结尾的连续子串。

然后针对前缀表到底要不要减一,这其实是不同KMP实现的方式,我们在中针对之前两个问题,分别给出了两个不同版本的的KMP实现。

其中主要理解j=next[x]这一步最为关键!

四、双指针总结

再次强调,双指针这种方法不属于任何一种数据结构专属的算法。一般而言,下边这几种数据结构都会经常用到双指针法,下边我们来总结一下用到双指针的常用场景。另外,我们再看几种会经常用到双指针的场景。

数组篇

首先,数组的指定元素的删除,若想要原地删除,双指针就是一个非常不错的方法。一新一旧,都从头部开始,遍历判断,一旦是目标值跳过,否则赋给新数组。移除元素

其次,数组重复元素的删除,若想要原地删除,也可以使用双指针,一新一旧。删除有序数组中的重复项

链表篇

首先,整个链表的反转,

其次,分组的反转,【这里我们为了提高效率,基本没有使用首尾双指针,而是使用的前后的双指针】

再有,相遇追及问题,环问题、倒数节点问题快慢指针。

这几种场景问题的我在前边有讨论过,不再赘述。

环形链表系列

倒数节点系列

链表高频题1

链表高频题2

字符串篇

首先,反转字符串

其次,字符串中指定字符的替换。

这两种类型上一篇blog已总结,包括本篇blog的第三部分也有部分总结,不再赘述。

N数之和

两数之和

三数之和

四数之和

n数之和

下边的这两篇有涉及到或者类似的问题,注意区分什么时候使用双指针,什么使用哈希表。

n=2

n>2

练习题目汇总(重点)

https://programmercarl.com/0027.%E7%A7%BB%E9%99%A4%E5%85%83%E7%B4%A0.html

https://programmercarl.com/0344.%E5%8F%8D%E8%BD%AC%E5%AD%97%E7%AC%A6%E4%B8%B2.html

https://programmercarl.com/%E5%89%91%E6%8C%87Offer05.%E6%9B%BF%E6%8D%A2%E7%A9%BA%E6%A0%BC.html

https://programmercarl.com/0151.%E7%BF%BB%E8%BD%AC%E5%AD%97%E7%AC%A6%E4%B8%B2%E9%87%8C%E7%9A%84%E5%8D%95%E8%AF%8D.html

https://programmercarl.com/0206.%E7%BF%BB%E8%BD%AC%E9%93%BE%E8%A1%A8.html

https://programmercarl.com/0142.%E7%8E%AF%E5%BD%A2%E9%93%BE%E8%A1%A8II.html

https://programmercarl.com/0015.%E4%B8%89%E6%95%B0%E4%B9%8B%E5%92%8C.html

https://programmercarl.com/0018.%E5%9B%9B%E6%95%B0%E4%B9%8B%E5%92%8C.html

发表评论

表情:
评论列表 (有 0 条评论,98人围观)

还没有评论,来说两句吧...

相关阅读

    相关 459. 重复字符串

    给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。 示例 1: 输入: "abab"