題目描述
給定一個字串,請你找出其中不含有重複字元的 最長子串 的長度。
示例1:
輸入: "abcabcbb" 輸出: 3 解釋: 因為無重複字元的最長子串是 "abc",所以其長度為 3。
示例2:
輸入: "bbbbb" 輸出: 1 解釋: 因為無重複字元的最長子串是 "b",所以其長度為 1。
示例3:
輸入: "pwwkew" 輸出: 3 解釋: 因為無重複字元的最長子串是 "wke",所以其長度為 3。 請注意,你的答案必須是 子串 的長度,"pwke" 是一個子序列,不是子串。
解法1:滑動視窗
滑動視窗是解決字串和陣列類問題的一個重要工具。就本地而言,我們使用如下解題思路:
- 假設輸入字串為:pwwkew
- 初始化map, key為字元,value為該字元在輸入字串中的位置。
- 初始化i=0,j=0。
- 檢視j所對應的元素newJValue是否否在與map中:
- 如果它在map中,則從map中刪除i所指向的元素,並將i向右滑動,繼續執行4。
- 如果它不在map中,則將其插入到map,並將j向右滑動,繼續執行4。並起來當前最大值m。
class Solution {
public:
int lengthOfLongestSubstring(string str) {
int i = 0;
int j = 0;
int m = 0;
int size = (int)str.size();
map<char, int> tmap;
while (i<size && j<size) {
if (tmap.find(str[j]) == tmap.end()) {
tmap.insert(pair<char, int>(str[j], j));
j++;
m = max(m, j-i);
} else {
tmap.erase(tmap.find(str[i]));
i++;
}
}
return m;
}
};
複製程式碼
優化程式碼
這裡的優化思路是:當i需要向右滑動的時候不需要一次一次的滑動,而是直接跳到新的重複元素。
舉例來說,對於測試用例:pwwkew來講。
當j=2,i=0是,map中已經有了pw了,對於j=2的w在map中已經存在w,所以此時需要將i右滑兩次,只是我們可以直接將i跳到2,而不用一步一步的滑動。具體程式碼如下:
int lengthOfLongestSubstring(string str) {
int i = 0;
int j = 0;
int m = 0;
int size = (int)str.size();
map<char, int> tmap;
while (j<size) {
if (tmap.find(str[j]) != tmap.end()) {
i = max(tmap.find(str[j])->second, i);
}
m = max(m, j-i+1);
tmap[str[j]] = j+1;
j++;
}
return m;
}
複製程式碼