一、概述
输入一个字符串,输出其最长连续的无重复字母的子串长度。
终于有一个自己写出的好一点的代码了。
二、分析
与第一题类似,在遍历的过程中,我们可以得到有助于求解的信息,使用哈希表保存这些信息。
如对于字符串“abcabcbb”,我们遍历如下:
第一个元素a,第一次遇到,哈希表存其位置0,更新begin为0,end为0,len为1;
第二个元素b,第一次遇到,哈希表存其位置1,更新begin为0,end为1,len为2;
第三个元素c,第一次遇到,哈希表存其位置2,更新begin为0,end为2,len为3;
第四个元素a,第二次遇到,这时,我们要将“从子串开始,到该元素”的所有元素的哈希表对应值重置,在此条件下就是把a对应的值置为-1。然后对此元素,哈希表存其位置3,更新begin为1,end为3,len为3;
第五个元素b,第二次遇到,哈希表存其位置4,更新begin为2,end为4,len为3;
第六个元素c,第二次遇到,哈希表存其位置5,更新begin为3,end为5,len为3;
第七个元素b,第三次遇到,哈希表存其位置6,更新begin为5,end为6,len为2;
第八个元素b,第四次遇到,哈希表存其位置7,更新begin为7,end为7,len为1;
最终ans取len最大值为3。
简而言之,思路如下:
从头遍历整个字符串,维护begin和end两个指针。
若某元素第一次遇到,更新end;
若某元素第二次遇到,将begin到该元素的所有哈希值重置,然后更新begin到此值的下一个,end为目前的i。
举例如“abcdecdefghijk”,最长子串应该是“cdefghijk”,在遍历到第一个e之后,遇到的c是第二次遇到,这时,要将a到c这三个值的哈希值重置,因为此时begin为d对应的3,end为c对应的5,子串为dec,再遇到ab还可以加入子串,因此要将其重置。
三、总结
Hash表的应用。同时注意字符串的处理。
PS:代码如下:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int ans=0;
int begin=0,end=0;
int Hash[128];
fill(Hash,Hash+128,-1);
int len=s.length();
for(int i=0;i<len;i++)
{
if(Hash[s[i]]==-1)
{
Hash[s[i]]=i;
end=i;
if(end-begin+1>ans)
ans=end-begin+1;
}
else
{
int temp=Hash[s[i]];
for(int j=begin;j<=Hash[s[i]];j++)
Hash[s[j]]=-1;
begin=temp+1;
Hash[s[i]]=i;
end=i;
if(end-begin+1>ans)
ans=end-begin+1;
}
}
return ans;
}
};