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