3. Longest Substring Without Repeating Characters
题目大意
Given a string s
, find the length of the longest substring without repeating characters.
中文释义
给定一个字符串 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^4
- 字符串
s
由英文字母、数字、符号和空格组成。
解题思路
方法:滑动窗口
这个解法使用滑动窗口的方法来寻找不含重复字符的最长子串。
通过维护一个字符到其最后出现位置的映射表 char_table
来追踪每个字符是否重复出现。
当 right
扫描到某个字符 c ,查询table_char[c]发现之前出现过,那么 left
指针移动到 table_char[c] + 1 的位置,移动的过程中要更新中间的table_char[] 重置为-1,因为它们都是丢弃的字符。
算法步骤
- 初始化一个大小为 256 的数组
char_table
来存储每个字符最后一次出现的索引位置,初始值全部设为 -1。 - 使用两个指针
left
和right
表示当前考虑的子串的开始和结束位置,并初始化最大长度maxLength
为 0。 - 遍历字符串
s
,对于每个字符s[right]
:- 如果
s[right]
已经在char_table
中出现过(即char_table[s[right]] != -1
),则移动left
指针,直到left
大于等于char_table[s[right]]
的位置,并将这个区间内的字符在char_table
中的值重置为 -1。 - 更新
s[right]
在char_table
中的位置为其当前索引right
。 - 更新最大长度
maxLength
为当前最大长度和right - left + 1
中的较大值。 - 移动
right
指针到下一个位置。
- 如果
- 返回
maxLength
作为结果。
class Solution {
public:
int lengthOfLongestSubstring(string s) {
vector<int> char_table(256, -1);
int left = 0, right = 0, maxLength = 0;
while (right < s.length()) {
if (char_table[s[right]] != -1) {
while (left < char_table[s[right]]) { char_table[s[left++]] = -1;}
left++;
}
char_table[s[right]] = right;
maxLength = max(maxLength, right - left + 1);
right++;
}
return maxLength;
}
};