#include <stdio.h>
int lengthOfLongestSubstring(char * s){
int l=1,ll=0,i=1,head=0,p;
if(s[0]=='\0')return 0;
while(s[i]!='\0')
{
for(p=head;p<i&&s[i]!=s[p];p++); //循环和前面对比是否由重复
if(p<i) //有重复项
{
if(l>ll) //这次长度大于上次的
ll=l;
l=l+head-p; // l长度改变,重新挂链
head=p+1; //连的长度从head到a[i],head是重复项的下一个数组元素如abcabc,a重复时,head变成b ,新链bca
}
else
{l++;
}
i++;
}
if(ll==0)ll=l;
return ll;
}
int main()
{
char s[100];
int length;
gets(s);
printf("%s\n",s);
length=lengthOfLongestSubstring(s);
printf("maxl:%d",length);
return 0;
}
第一次出错:
执行出错信息:AddressSanitizer: heap-buffer-overflow on address 0x6020000000d1 at pc 0x000000401799 bp 0x7ffc8d793650 sp 0x7ffc8d793648
最后执行的输入:""
原因:没写字符串为0的情况
修正:if(s[0]=='\0')return 0;
第二次出错:
输入:"aab"
输出:1
预期:2
原因:未考虑最长出现在最后循环完毕的情况下,ll没和l再来个对比。
最后
上面以时间复杂度换取空间复杂度。下面这个相反
int lengthOfLongestSubstring(char * s){
int ascii[128];
char *left=s,*right=s;
int curlen=0,maxlen=0;
int index;
memset(ascii,0,128);
int len=strlen(s);
printf("len:%d",len);
if(len==0||len==1)
return len;
while(right!=s+len)
{
index=(int)(*right); //字符转换为ascii值
if(ascii[index]==1)
{
while(*left!=*right)
{
curlen--;
ascii[(int)(*left)]=0;
left++;
}
left++;
}
else
{
curlen++;
ascii[index]=1; //目前链已存在此字符
}
right++;
if(maxlen<curlen)
maxlen=curlen;
}
return maxlen;
}
这个方法利用空间换时间,其中部分语法借鉴他人,感觉更好些。