3. 无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
解法一:
//时间复杂度O(n), 空间复杂度O(n)
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_set<char> us;
int len = s.size(), maxLen = 0;
int left = 0;
for(int i = 0; i < len; i++) {
if(us.count(s[i])) {
int j = left;
while(s[j] != s[i]) us.erase(s[j++]);
us.erase(s[j++]);
left = j;
}
us.insert(s[i]);
maxLen = max(maxLen, i - left + 1);
}
return maxLen;
}
};
解法二(leetcode官方题解):
//时间复杂度O(n), 空间复杂度O(n)
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int len = s.size();
int i = 0, j = 0, maxLen = 0;
unordered_set<char> us;
while(j < len) {
if(us.count(s[j])) us.erase(s[i++]);
else us.insert(s[j++]);
maxLen = max(maxLen, j - i);
}
return maxLen;
}
};
解法三(优化)
//时间复杂度O(), 空间复杂度O()
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int i = 0;
int n = s.size(), maxLen = 0;
unordered_map<char, int> um;
for(int j = 0; j < n; j++) {
if(um.count(s[j])) {
i = max(i, um[s[j]] + 1);//!!
}
maxLen = max(maxLen, j - i + 1);
um[s[j]] = j;
}
return maxLen;
}
};
思路:
维护一个滑动窗口。i指向窗口最左端,j指向最右端。哈希表um记录字符最后出现的位置。遍历s,如果um中没出现过字符c,就将其记录在um中。如果在滑动窗口内出现过,就更新窗口左边界。如上。
2019/09/12 12:33