Longest Substring Without Repeating Characters 解法
第二周题目
难度:Media
LeetCode题号:3
题目
Description:
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.
思考
错误想法
一开始想的是用map来储存每一个字符,从左往右扫每一个字符,
如果在map里面遇到相同的,则将前面这些算为一个子字符串计算长度。
比如“abcopce”,这里两个c是重复的,当扫描到第二个c时将第二个c前面的算一个子字符串,然后从第二个c开始继续往后扫描计算。
之前一直不知道是从第一个重复的字符那里开始往后,所以没想到方法,就去参考别人的,以下为参考内容
时间复杂度为O(n)的方法
使用i和j两个指针进行搜索,i代表候选的最长子串的开头,j代表候选的最长子串的结尾。
先假设i不动,那么在理想的情况下,我们希望可以一直右移j,直到j到达原字符串的结尾,
此时j-i就构成了一个候选的最长子串。每次都维护一个max_length,就可以选出最长子串了。实际情况是,不一定可以一直右移j,如果字符j已经重复出现过(假设在位置k),就需要停止右移了。记录当前的候选子串并和max_length做比较。接下来为下一次搜寻做准备。
在下一次搜寻中,i应该更新到k+1。这句话的意思是,用这个例子来理解,abcdef是个不重复的子串,abcdefc中(为了方便记录为abc1defc2),c1和c2重复了。那么下一次搜寻,应该跨过出现重复的地方进行,否则找出来的候选串依然有重复字符,且长度还不如上次的搜索。所以下一次搜索,直接从c1的下一个字符d开始进行,也就是说,下一次搜寻中,i应该更新到k+1。
参考答案:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
bool exist[256] = {false};
int maxLen = 0;
int i = 0, j = 0, length = s.length();
while (j < length) {
if (exist[s[j]]) {
maxLen = max(maxLen, j - i);
while (s[i] != s[j]) {
exist[s[i]] = false;
i++;
}
i++;
} else {
exist[s[j]] = true;
}
j++;
}
maxLen = max(maxLen, length - i);
return maxLen;
}
};