Longest Substring Without Repeating Characters
解题思路:
1、最直观的想法,每扫描一个字符,与前面最后一个未重复之后的字符比较,直到遇到相同的字符。这里要时刻记录最后一个未重复的字符的位置。
class Solution { public: int lengthOfLongestSubstring(string s) { int maxLen = 0; int noRepeatStart = 0; int len=s.length(); for(int i=0; i<len; i++){ char endChar = s[i]; char localMaxLen = 1; for(int j=i-1; j>=noRepeatStart; j--){ if(s[j]==endChar){ noRepeatStart=j+1; break; } localMaxLen++; } if(localMaxLen>maxLen){ maxLen=localMaxLen; } } return maxLen; } };2、上述代码中,时间复杂度最坏情况是O(n^2),显然不行,我们可以用一个hash表记录每个字符最后出现的位置。下面是代码。
class Solution { public: int lengthOfLongestSubstring(string s) { int maxLen = 0; int noRepeatStart = 0; int localMaxLen = 0; int len=s.length(); map<char, int> charToIndex; //某个字符最近出现的位置 for(int i=0; i<len; i++){ map<char, int>::iterator it=charToIndex.find(s[i]); if(it==charToIndex.end()||it->second<noRepeatStart){ localMaxLen++; if(localMaxLen>maxLen){ maxLen=localMaxLen; } }else{ noRepeatStart=it->second+1; localMaxLen=i-it->second; } charToIndex[s[i]]=i; } return maxLen; } };3、然而,2方法在leetcode上跑仍然很慢,甚至时间大于1方法。肯定哪里出现问题了。其实char的取值范围最多为256,可以用一个数组来记录每个字符最后出现的位置,这样就省去了map的查找开销。这是一个很好的思路。下面是代码:
class Solution { public: int lengthOfLongestSubstring(string s) { int maxLen = 0; int noRepeatStart = 0; int localMaxLen = 0; int len=s.length(); int charToIndex[256]; //char只有256个 memset(charToIndex, -1, 256*sizeof(int)); for(int i=0; i<len; i++){ if(charToIndex[s[i]]<noRepeatStart){ localMaxLen++; if(localMaxLen>maxLen){ maxLen=localMaxLen; } }else{ noRepeatStart=charToIndex[s[i]]+1; localMaxLen=i-charToIndex[s[i]]; } charToIndex[s[i]]=i; } return maxLen; } };
[LeetCode] Longest Substring Without Repeating Characters
原文地址:http://blog.csdn.net/kangrydotnet/article/details/45080727