用滑动窗口的思想来做。用一个unordered_map来查询之前的char有没有在现在的窗口中。
class Solution { public: int lengthOfLongestSubstring(string s) { unordered_map<char,int>mp; int ans=0,now=0;//now is the window's instant length int b=0,e=0;//the window's begin and end int len=s.length(); for(int i=0;i<len;i++){ if(mp.count(s[i])==1&&mp[s[i]]>=b&&mp[s[i]]<e){//in the window b=mp[s[i]]+1; e=i+1; now=e-b; if(ans<now){ ans=now; } mp[s[i]]=i; } else{//not in the window mp[s[i]]=i; now++; e++; if(ans<now){ ans=now; } } } return ans; } };
其实,还有更好的做法。就是hash表并没有必要用map来表示。用一个数组就可以了。因为ASCII码的字符最多就255个。所以开一个256大小的数组足够了。
这种方法的妙处在于不把字符当成字符本身去处理,而是处理它对应的ASCII码,这样就把map变成普通数组也可以了,思路是一样的,只不过map是以字符为下标,这里的普通数组是以它的ASCII码为下标。
class Solution { public: int lengthOfLongestSubstring(string s) { int hash[256]; memset(hash,-1,sizeof(hash)); int b=0,ans=0; int len=s.length(); for(int i=0;i<len;i++){ b=max(b,hash[s[i]]+1); hash[s[i]]=i; ans=max(ans,i-b+1); } return ans; } };