求一个字符串中不含重复字母的最大子串的长度。
【思路】
1.用临时tmp记录长度,遇到重复字母把tmp当前值赋给要返回的length,tmp归零
比较tmp和length,当tmp>length时,更新length。
2.每个字母向前遍历是否有重复字母,用哈希表。
3.反复提交代码不能通过后看了题目tag,知道需要双指针,用一个begin指向重新计数的开始处,i-begin得到当前长度,
每次遇到重复就把begin赋值为哈希表该字母对应的序号的后一个。
注意:哈希表还要更新重复字母的序号,否则每次都和第一次出现过的比,begin赋值不正确。
【my code】
int lengthOfLongestSubstring(string s) { int length=s.size(); int l=0,tmp=0; int begin=0,end=0; unordered_map<char,int> charmap; for(int i=0; i<length; i++){ if(charmap.find(s[i])!=charmap.end()){ if(l<tmp) l=tmp; tmp=i-begin;//eg:ohomm if(begin<charmap[s[i]]+1)//eg:abba begin=charmap[s[i]]+1; } charmap[s[i]]=i; } if(l<tmp) l=tmp; return max(l,length-begin); }
【总结】
一把辛酸泪!
改了无数遍!最后结果还特别差……哭晕。
看到一个新解法,新开一个数组,排名十分靠前,明天细细分析。
【other code】
int lengthOfLongestSubstring(string s) { int locs[256];//保存字符上一次出现的位置 memset(locs, -1, sizeof(locs)); int idx = -1, max = 0;//idx为当前子串的开始位置-1 for (int i = 0; i < s.size(); i++) { if (locs[s[i]] > idx)//如果当前字符出现过,那么当前子串的起始位置为这个字符上一次出现的位置+1 { idx = locs[s[i]]; } if (i - idx > max) { max = i - idx; } locs[s[i]] = i; } return max; }
【分析】
1.用int数组代替hash表,因为字符的int值不会超过256,所以开一个int locs[256]足够,每次用char的int值做索引。
2.思路和我修正过后的思路一致,如果当前字符在以前出现过,就把起始位置设为上一次出现的位置,如果没有出现过就记录当前长度,最后不要忘了更新重复出现的字符索引。
3.哈希表的思路一定要牢记,但不一定非得用unordered类型。
耗时:22ms,排名最前。