问题重述:
给定一个字符串 s
,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是"abc" ,所以其长度为 3。
示例 2:
输入: s = "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是"b",所以其长度为 1。
示例 3:
输入: s = "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是"wke",所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke"是一个子序列,不是子串。
提示:
0 <= s.length <= 5 * 104
s
由英文字母、数字、符号和空格组成
代码实现:
#include <unordered_map>
#include <algorithm>
class Solution {
public:
int lengthOfLongestSubstring(std::string s) {
int n = s.size();
std::unordered_map<char, int> mp; // 记录每个字符最近出现的位置
int left = 0, right = 0, ans = 0; // 窗口的左右边界和最长子串的长度
while (right < n) {
if (mp.find(s[right]) == mp.end()) { // 如果当前字符没有出现过
mp[s[right]] = right; // 记录当前字符最近出现的位置
ans = std::max(ans, right - left + 1); // 更新最长子串的长度
right++; // 将右边界右移
} else { // 如果当前字符已经出现过
mp.erase(s[left]); // 将左边界左移
left++; // 将左边界左移
}
}
return ans;
}
};
这是一个典型的滑动窗口问题,我们可以用哈希表来记录每个字符最近出现的位置,然后遍历字符串s,对于每个字符,如果它最近出现的位置不在窗口内,就将它的出现次数加1,然后将窗口的长度加1。如果字符最近出现的位置在窗口内,就将窗口的长度取最大值。最后返回窗口的长度即可。