3. 无重复字符的最长子串 - 力扣(LeetCode)

给定一个字符串 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 由英文字母、数字、符号和空格组成

双层循环

class Solution {
public:
int lengthOfLongestSubstring(string s) {
if(s.size()==0)return 0;
int maxLength=0;
map<char,bool> hash;
for(int i=0;i<s.size();i++){
hash.clear();
for(int j=i;j<s.size();j++){
if(!hash[s[j]]){
hash[s[j]]=1;
maxLength=max(maxLength,j-i+1);//这里也要保持更新,全不重复的情况
}else{
maxLength=max(maxLength,j-i);//已经是重复字符的位置
break;
}

}

}
return maxLength;
}
};

滑动窗口求解

class Solution {
public:
int lengthOfLongestSubstring(string s) {
int maxLength = 0;
unordered_set<char> chars; // 哈希集合记录当前窗口中的字符
int n = s.size();
int left = 0, right = 0; // 滑动窗口的左右指针

while (right < n) {
// 左指针右移时,从集合中移除前一个字符
if (left != 0) {
chars.erase(s[left - 1]);
}
// 尽可能扩展右指针,直到遇到重复字符
while (right < n && !chars.count(s[right])) {
chars.insert(s[right]);
right++;
}
// 更新最大长度(窗口长度为 right - left)
maxLength = max(maxLength, right - left);
left++; // 移动左指针
}
return maxLength;
}
};