🌈hello,你好鸭,我是Ethan,西安电子科技大学大三在读,很高兴你能来阅读。
✔️目前博客主要更新Java系列、项目案例、计算机必学四件套等。
🏃人生之义,在于追求,不在成败,勤通大道。加油呀!
🔥个人主页:Ethan Yankang
🔥推荐:史上最强八股文 || 一分钟看完我的上千篇博客
🔥温馨提示:划到文末发现专栏彩蛋 点击这里直接传送
🔥本篇概览:数据结构与算法 || 详细讲解了利用KMP算法来判断原串是否是由重复的子字符串构成的。🌈⭕🔥
【计算机领域一切迷惑的源头都是基本概念的模糊,算法除外】
目录
🌈序言
算法乃我长久之志也,此关必过。今日得此代码随想录之良品辅助,应按此路学之习之,而长久不可懈怠。
前一系列文章详细讲解了利用两串相加掐头去尾判断是否为重复子串构成的算法,建议先将这部分知识掌握之后再来学习本篇内容,点击查看。
🔥 代码随想录39——字符串7——两串相加递归——重复的子字符串-CSDN博客
🌈引出
这节课利用经典KMP算法来介绍如何判断是否是重复的子字符串。
题目:459.重复的子字符串
给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。
示例 1:
- 输入: "abab"
- 输出: True
- 解释: 可由子字符串 "ab" 重复两次构成。
示例 2:
- 输入: "aba"
- 输出: False
示例 3:
- 输入: "abcabcabcabc"
- 输出: True
- 解释: 可由子字符串 "abc" 重复四次构成。 (或者子字符串 "abcabc" 重复两次构成。)
剖析题干重点:
🔥思路分析:
在一个串中查找是否出现过另一个串,这是KMP的看家本领。那么寻找重复子串怎么也涉及到KMP算法了呢?
KMP算法中next数组为什么遇到字符不匹配的时候可以找到上一个匹配过的位置继续匹配,靠的是有计算好的前缀表。 前缀表里,统计了各个位置为终点字符串的最长相同前后缀的长度。
那么 最长相同前后缀和重复子串的关系又有什么关系呢。
可能很多录友又忘了 前缀和后缀的定义,再回顾一下:
- 前缀是指不包含最后一个字符的所有以第一个字符开头的连续子串;
- 后缀是指不包含第一个字符的所有以最后一个字符结尾的连续子串
以下,划重点!!!
在由重复子串组成的字符串中,减去最长相等前后缀的子串就是最小重复子串。
🌈最终代码:
class Solution {
public boolean repeatedSubstringPattern(String s) {
if (s.equals("")) return false;
int len = s.length();
// 原串加个空格(哨兵),使下标从1开始,这样j从0开始,也不用初始化了
s = " " + s;
char[] chars = s.toCharArray();
int[] next = new int[len + 1];
// 构造 next 数组过程,j从0开始(空格),i从2开始
for (int i = 2, j = 0; i <= len; i++) {
// 匹配不成功,j回到前一位置 next 数组所对应的值
while (j > 0 && chars[i] != chars[j + 1]) j = next[j];
// 匹配成功,j往后移
if (chars[i] == chars[j + 1]) j++;
// 更新 next 数组的值
next[i] = j;
}
// 最后判断是否是重复的子字符串,这里 next[len] 即代表next数组末尾的值
if (next[len] > 0 && len % (len - next[len]) == 0) {
return true;
}
return false;
}
}
今日问题:
🔥今日总结:
核心点:
1.理论基础:
在由重复子串组成的字符串中,减去最长相等前后缀的子串就是最小重复子串。
这里只需要判断这个子串是否可以被原串整除。
2.判断条件
if (next[len] > 0 && len % (len - next[len]) == 0)
📣非常感谢你阅读到这里,如果这篇文章对你有帮助,希望能留下你的点赞👍 关注❤收藏✅ 评论💬,大佬三连必回哦!thanks!!!
📚愿大家都能学有所得,功不唐捐!
👇下面是专栏彩蛋系列,你会喜欢的!(为了避免影响算法的简洁与优美,这里直接将之前的几十个专栏简化为3个部分,不过你点击开后发现惊喜。)👇
💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖
热门专栏
💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖