今天下午刷力扣遇到这么一道问题。看着挺简单(其实也挺简单)题主还是研究了一段时间才写出来的。
下面和大家分享一下我的思路。
题目是这样的
给出一个字符串 S,考虑其所有重复子串(S 的连续子串,出现两次或多次,可能会有重叠)。
返回任何具有最长可能长度的重复子串。(如果 S 不含重复子串,那么答案为 "1"。)
刚看到这道题想到的是暴力搜索,也就是便利所有子串,但如果自底向上算的话又未免太复杂了。
- 在这里我们不妨设母串的长度为n,那么如果想遍历出所有子串,如果用循环的简单嵌套的话,时间复杂度为,这未免有点离谱,但是头铁的我还是试了一下,结果疯狂超时。
- 而且作为勤快(懒惰)的西电学渣,我看稍微复杂一点的代码都挺头疼的。
以下就是我的分析。
思路:这是一道移动窗口问题,也可以理解成贪吃蛇和壁虎的结合体(字符串的头部是贪吃蛇,尾部是壁虎)不同的字符就是食物,被吃掉后字符串就增长,而相同的字符(尾部)就相当于荆棘,遇到荆棘小壁虎就会断掉一点尾巴(究竟断多少是这道题的核心)
那怎么进行循环呢:
首先让头不断地往前走,如果遇到了重复的字符,那么队列(可以理解为不断移动的数组)就要前移,直到不重复为止
这样可以遍历出所有符合条件的字串的长度
下面是我的代码
习惯用数组下标的xd可以尝试用数组表示法解一下,这里我就不给出下标表示的解法了(懒)
int lengthOfLongestSubstring(char * s){
char *tail=s;
char *head =s;
char *p;
int ans=0;
while(*head!=0){ /*控制小蛇的头*/
for(p=tail;p<head;p++){ /*控制壁虎的尾巴*/
if(*p==*head){
tail =p+1; /*在第一次重复出断尾巴,因为不可能有第二处 */
break;
}
}
ans =(head-tail+1)>ans?(head-tail+1):ans;
head++;
}
return ans;
}
这就是我的解法了,可以看出时间复杂度还是挺低的();
各位老板给孩子点个赞把。