3. Longest Substring Without Repeating Characters
題目:
Given a string, find the length of the longest substring without repeating characters.
Example:
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記錄各個字符的下標,首先將所有的下表初始化為-1,然后向后遍歷的過程中記錄當前字符的下標,并將當前字符的下標與上一個相同字符的下標做差值,即可得到它們之間無重復字符的子串。然后用Max記錄更新最大子串數,并更新map存儲的下標值,即從這個重復值重新開始數字符串的數(最大無重復字符子串必定在兩個重復字符之間,或者是整個字符串的長度)
這種方法好像被叫做滑動窗口法
"滑動窗口"
比方說 abcabccc 當你右邊掃描到abca的時候你得把第一個a刪掉得到bca,
然后"窗口"繼續向右滑動,每當加到一個新char的時候,左邊檢查有無重復的char,
然后如果沒有重復的就正常添加,
有重復的話就左邊扔掉一部分(從最左到重復char這段扔掉),在這個過程中記錄最大窗口長度
代碼(C++)
class Solution {
public:
int lengthOfLongestSubstring(string s) {
map<char,int> book;
int i,Max=0,pre=-1;
for(i=0;i<s.length();i++)
book[s[i]]=-1;
for(i=0;i<s.length();i++)
{
pre=max(pre,book[s[i]]);//更新map中各個字符的下標
Max=max(Max,i-pre); //保存暫時的最大無重復子串長度
book[s[i]]=i; //計算差值后繼續更新
}
return Max;
}
};
解法二
解析
建立一個256位大小的整型數組來代替哈希表,這樣做的原因是ASCII表共能表示256個字符,所以可以記錄所有字符,然后我們需要定義兩個變量res和left,其中res用來記錄最長無重復子串的長度,left指向該無重復子串左邊的起始位置,然后我們遍歷整個字符串,對于每一個遍歷到的字符,如果哈希表中該字符串對應的值為0,說明沒有遇到過該字符,則此時計算最長無重復子串,i - left +1,其中i是最長無重復子串最右邊的位置,left是最左邊的位置,還有一種情況也需要計算最長無重復子串,就是當哈希表中的值小于left,這是由于此時出現過重復的字符,left的位置更新了,如果又遇到了新的字符,就要重新計算最長無重復子串。最后每次都要在哈希表中將當前字符對應的值賦值為i+1。
代碼(C++)
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int m[256] = {0}, res = 0, left = 0;
for (int i = 0; i < s.size(); ++i) {
if (m[s[i]] == 0 || m[s[i]] < left) {
res = max(res, i - left + 1);
} else {
left = m[s[i]];
}
m[s[i]] = i + 1;
}
return res;
}
};