3.无重复字符的最长子串

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串的长度。

示例 1:

1
2
3
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3

示例 2:

1
2
3
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1

示例 3:

1
2
3
4
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Solution {
// 定义一个公开的方法 lengthOfLongestSubstring,接受一个字符串 s 作为参数,并返回一个整型值。
public int lengthOfLongestSubstring(String s) {
// 定义一个整型变量 left 用于追踪当前考察的子串的开始位置。
int left = 0;
// 创建一个字符集合 set,用于存储当前考察的子串中的字符,以便快速检查字符是否重复。
Set<Character> set = new HashSet<>();
// 将字符串 s 转换为字符数组 ans,以便逐个访问每个字符。
char[] ans = s.toCharArray();
// 定义一个整型变量 x 用于记录最长无重复字符子串的长度。
int x = 0;
// 使用一个 for 循环从左到右遍历字符数组 ans。
for (int right = 0; right < ans.length; right++) {
// 如果字符集 set 中不包含当前字符 ans[right],则将其添加到 set 中。
if (!set.contains(ans[right])) {
set.add(ans[right]);
} else {
// 如果字符集中已包含 ans[right],则通过 while 循环移除从 left 到当前重复字符之间的所有字符。
while (ans[left] != ans[right]) {
set.remove(ans[left++]);
}
// 将 left 移动到重复字符的下一个位置。
left++;
}
// 更新 x 的值,保留最大的子串长度。计算当前无重复子串的长度为 right-left+1。
x = Math.max(x, right - left + 1);
}
// 返回找到的最长无重复字符子串的长度。
return x;
}
}