无重复字符的最长子串
题目描述
题目:给定一个字符串 s,请找出其中不含有重复字符的最长子串的长度。
示例 1:
- 输入:
s = "abcabcbb" - 输出:
3 - 解释: 因为无重复字符的最长子串是
"abc",所以其长度为3。
示例 2:
- 输入:
s = "bbbbb" - 输出:
1 - 解释: 因为无重复字符的最长子串是
"b",所以其长度为1。
示例 3:
- 输入:
s = "pwwkew" - 输出:
3 - 解释: 因为无重复字符的最长子串是
"wke",所以其长度为3。请注意,你的答案必须是子串的长度,"pwke"是一个子序列,不是子串。
提示:
0 <= s.length <= 5 * 10^4s由英文字母、数字、符号和空格组成
解题思路
实现原理和思路
-
使用滑动窗口法:
- 滑动窗口是一种用于解决数组或字符串相关问题的常用技巧,通过维护一个左右边界来表示一个“窗口”,窗口中的元素满足特定条件。
- 在本题中,滑动窗口的目标是找到一个不含重复字符的子串。
- 通过两个指针
l(左边界)和r(右边界)来动态调整窗口的大小,l和r都初始化为 0,表示从字符串的第一个字符开始。
-
利用哈希表记录字符出现情况:
- 使用一个
unordered_map<char, int>作为哈希表,记录窗口中每个字符是否存在,或者记录字符在窗口中的出现次数。 - 当窗口的右边界
r移动时,逐个将字符加入到哈希表中,检查是否有重复字符。
- 使用一个
-
窗口扩展和收缩:
- 如果右边界
r指向的字符s[r]不在哈希表中,说明没有重复字符,当前窗口仍然符合条件,此时将字符s[r]加入到哈希表,并继续将右边界r右移,扩展窗口。 - 如果右边界
r指向的字符s[r]已经存在于哈希表中,说明出现了重复字符,当前窗口不再符合条件。此时需要缩小窗口,具体做法是通过移动左边界l来排除左边的字符,直到窗口中不再包含重复字符。
- 如果右边界
-
维护最大长度:
- 在每次右边界
r扩展时,都计算当前窗口的长度r - l,并更新记录最长无重复字符子串的长度ans。 - 每次更新
ans时,ans = max(ans, r - l),确保记录的是最长的无重复子串的长度。
- 在每次右边界
-
最终返回结果:
- 当右边界
r遍历完整个字符串后,ans中记录的就是最长无重复字符子串的长度,返回ans即可。
- 当右边界
具体步骤总结
- 初始化变量
l = 0(左边界),r = 0(右边界),ans = 0(最长无重复子串长度),和哈希表map用来记录窗口内字符的出现情况。 - 使用
while (r < n)循环遍历字符串,右边界r每次右移,动态调整窗口:- 当
s[r]不在map中时,将字符加入哈希表,扩大窗口。 - 当
s[r]已经在map中时,缩小窗口,通过移动左边界l,直到窗口内无重复字符。 - 每次调整窗口后,计算当前窗口长度
r - l,更新ans。
- 当
- 最后,返回
ans,即为最长无重复子串的长度。
代码实现
C++版本代码实现:
class Solution {
public:
int le

最低0.47元/天 解锁文章
1179

被折叠的 条评论
为什么被折叠?



