题目:
Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without
repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1.
思路:
1.题目要求,找出字符串中无重复字符的最长子串的长度,最直接的方法是从前到后为每个字符遍历一遍字符串,这样算法复杂度为O(n*n);
2.该问题可以在O(n)复杂度内完成;
3.具体思路为设立前后两个指针,分别为front和back,初始均为0,使用一个bool数组记录当前字符是否出现过,该数组以字符ascll码作为下标;
4.back指针先走,若当前字符在bool数组中未出现过,则将相应位置1,back指针继续向后走;
5.若back所指当前字符在bool数组中出现过,则可以计算back-front,此值为此段无重复字符子串的长度(maxlen),然后front指针开始向后走,直到找到相同字符,将此字符在bool数组中对应位置0(因为新子串需要从front指向的重复字符的下一个位置开始计算,在新子串中,front之前的字符均为出现过);
6.此后back与front同步向后走一步,开始计算新的子串,直到back指针走到字符串末尾;
7.在遍历结束后,需要比较当前maxlen与len-front的值,取最大值,因为若遇到abcde这样的情况,maxlen=0,len-front=5;
8.该算法在最坏情况下线性遍历两次字符串(back一次,front一次),故时间复杂度为O(n)。
代码:
class Solution{
public:
int lengthOfLongestSubstring(string s){
int front=0;
int back=0;
int len=s.length();
int maxlen=0;
bool exist[200]={false};
while(back<len)
{
if(!exist[s[back]])
{
exist[s[back]]=true;
++back;
}
else
{
maxlen=max(maxlen,back-front);
while(s[front]!=s[back])
{
exist[s[front]]=false;
++front;
}
++front;
++back;
}
}
maxlen=max(maxlen,len-front);
return maxlen;
}
};
补充:
1.对于遍历问题,应尽量考虑如何减少无谓遍历;
2.bool数组可使用acsll码做下标是本题的一个小技巧。