459. 重复的子字符串 - 力扣(LeetCode)
看题解前:
1、最开始想的是,先遍历字符串找到第一个与首字母相同的字母下标,然后依次匹配查看是否相等。例如abab,找到第一个与首字母相同的下标index为2,然后i从0-index,依次和index+1-index+index相比较每个字母是否相等即可。
错误点:假定字符串为ababad,上述解法会返回true,实际是false
2、原字符串末尾+原字符串,然后去掉首字母和尾字母,最后在该串中查找原字符串,找到返回true,没找到返回false。例如abcabc;+原字符串后:abcabcabcabc;去头去尾后:bcabcabcab;在该串中查找abcabc,找到返回true。
看题解后:KMP;返回为true的字符串满足:原字符串-最长相等前后缀=最小重复子串。
先给出前后缀定义:前缀指包含第一个字符不包含最后一个字符的连续子串,后缀为包含最后一个字符不包含第一个字符的连续字串。
为举例方便,下面是用ababab。
前缀:a,ab,aba,abab,ababa
后缀:b,ab,bab,abab,babab
最长相等前后缀就是在前后缀里面找到相等的且最长的即可,相等的有:ab,abab;再取最长即为abab;原字符串ababab-最长相等前后缀abab=最小重复字串ab。
KMP中next数组就保存了最长相同前后缀,假定用len保存字符串长度,next[len-1]就保存了最长相等前后缀的长度len-next[len-1]即为最小重复字串长度,假定len%(最小重复子串长度)为0,即原字符串有重复的子字符串。
总结KMP思路:
1、构造next数组
2、判断len%(len-next[len-1])是否为0,为0返回true,不为0返回false。