classSolution { public: intlengthOfLongestSubstring(string s){ unordered_set<char> window; int left = 0, ans = 0;
for (int right = 0; right < s.size(); right++) { while (window.count(s[right])) { window.erase(s[left]); left++; } window.insert(s[right]); ans = max(ans, right - left + 1); }
return ans; } };
时间复杂度:O(n)(right 和 left 都是单向移动,最多各走 n 步,均摊下来是线性)
空间复杂度:O(min(n, m))
比暴力法快一个量级,但左指针有时要一步一步挪,不是最快的收缩方式。
最优(滑动窗口 + 哈希映射)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classSolution { public: intlengthOfLongestSubstring(string s){ unordered_map<char, int> lastIndex; // 字符 -> 最后出现的下标 int left = 0, ans = 0;
for (int right = 0; right < s.size(); right++) { char c = s[right]; if (lastIndex.count(c) && lastIndex[c] >= left) { left = lastIndex[c] + 1; // 直接跳过重复字符,无需逐步移动 } lastIndex[c] = right; ans = max(ans, right - left + 1); }
classSolution { public: intlengthOfLongestSubstring(string s){ int lastIndex[256]; fill(begin(lastIndex), end(lastIndex), -1); int left = 0, ans = 0;
for (int right = 0; right < s.size(); right++) { unsignedchar c = s[right]; if (lastIndex[c] >= left) { left = lastIndex[c] + 1; } lastIndex[c] = right; ans = max(ans, right - left + 1); }