Given a string, find the length of the longest substring without repeating characters.
Examples:
Given "abcabcbb"
, the answer is "abc"
, which the length is 3.
Given "bbbbb"
, the answer is "b"
, with the length of 1.
Given "pwwkew"
, the answer is "wke"
, with the length of 3. Note that the answer must be a substring, "pwke"
is a subsequence and not a substring.
Subscribe to see which companies asked this question.
题解:这到题的最优解肯定是O(n),理论是这样的,我的解法接近于O(n),但是相比于最优解还是差一点;讲一下我的思路:将字符串从头到尾遍历一遍,遍历的过程中,使用无序图unordered_map <char,int>,关键值是char,int是该char字符遍历到i为止的最新位置;和起始start,标记当前无重复子字符串起始位置,初始值当然是0。当遍历到map中已经存在该字符char时,首先检查现在无重复字符串的长度与max的大小,决定是否对max重新赋值;然后再确定start的值,start要满足一个条件,新的start必需要比旧start大,因为,我们新检查到的重复的char,有可能是在start前面的,比如abba,当遍历到第是s[2] = b时,我们发现map中已经存在<b,1>,那么,start会等于s[1]的后面一个点,即start = 2;max = 2;此时map中存在<a,0><b,2>,当遍历s[3] = a时,但是此时检查到的重复a的位置是0,比start还小;如果从0位置开始计数,没有意义,因为a已经是ab无重复子字符串的一部分,所以start 还是 2;再者就是start的赋值,因为start是从重复的字符后面一个算起的,所以start 可以=it->second +1 也可以=ls[s[i]] +1 ;说一下可以优化的地方吧,总感觉it = ls.find(s[i]).可以用某种方法代替,因为ls[s[i]]+1 可以代替it->second +1 就没有使用map的必要,好吧用数组;
解法一:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int i;
int max = 0;
int start = 0;
unordered_map<char,int> ls;
unordered_map<char, int>::iterator it;
for( i = 0; i < s.size();i++) {
it = ls.find(s[i]);
if(it != ls.end()){
max = max > i - start ? max : i - start;
start = start > (it->second + 1) ? start : it->second + 1;
}
ls[s[i]] = i;
}
max = max>i - start ? max : i - start;
return max;
}
};
结果如下:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int i;
int max = 0;
int start = 0;
vector<int> ls(256,-1);
for( i = 0; i < s.size();i++) {
if(ls[s[i]] != -1 && (ls[s[i]] + 1)>start){
max = max > i - start ? max : i - start;
start = ls[s[i]] + 1;
}
ls[s[i]] = i;
}
max = max>i - start ? max : i - start;
return max;
}
};
结果如下: