Problem: 3. 无重复字符的最长子串
题目
3. 无重复字符的最长子串
给定一个字符串 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
由英文字母、数字、符号和空格组成
思考过程
在这道题目中,我们要找到字符串中不含重复字符的最长子串的长度。最直接的方法是枚举所有可能的子串,然后检查它们是否有重复字符,但这显然会非常低效。为了解决这个问题,我们需要想出一种更高效的方法。
解题思路
我们可以使用滑动窗口(Sliding Window)的方法来解决这个问题。滑动窗口是一种非常实用的算法技巧,尤其是在数组或字符串的子序列、子数组问题中。具体来说,我们会维护一个动态窗口,并且用一个 Set
来记录窗口中所有字符的集合。
- 定义窗口边界:我们使用两个指针
i
和j
来定义窗口的左右边界。i
代表当前字符的位置,j
是窗口的左边界。 - 窗口移动:我们遍历字符串,每次将
i
指向的字符添加到Set
中。如果添加成功(即当前字符未出现在窗口中),继续遍历。如果添加失败(即当前字符已在窗口中),我们将res
更新为当前窗口的最大长度,并开始移动j
来缩小窗口直到可以重新添加当前字符为止。 - 更新结果:我们在每次窗口成功移动后,更新结果的最大值。
图解
Code
class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length();
Set<Character> set = new HashSet<>();
int res = 0;
char[] str = s.toCharArray();
for(int i = 0, j = 0; i < n; i++){
if(set.add(str[i])){
continue;
}
res = Math.max(res, set.size());
while(j < n && str[j] != str[i]){
set.remove(str[j++]);
}
j++;
}
res = Math.max(res, set.size());
return res;
}
}
func lengthOfLongestSubstring(s string) int {
n := len(s)
set := make(map[byte]struct{})
res := 0
j := 0
for i := 0; i < n; i++ {
if _, found := set[s[i]]; !found {
set[s[i]] = struct{}{}
continue
}
if len(set) > res {
res = len(set)
}
for j < n && s[j] != s[i] {
delete(set, s[j])
j++
}
j++
}
if len(set) > res {
res = len(set)
}
return res
}
var lengthOfLongestSubstring = function(s) {
let n = s.length;
let set = new Set();
let res = 0;
let str = s.split('');
for (let i = 0, j = 0; i < n; i++) {
if (set.has(str[i])) {
res = Math.max(res, set.size);
while (j < n && str[j] !== str[i]) {
set.delete(str[j++]);
}
j++;
} else {
set.add(str[i]);
}
}
res = Math.max(res, set.size);
return res;
};
function lengthOfLongestSubstring(s: string): number {
let n = s.length;
let set = new Set<string>();
let res = 0;
let str = s.split('');
for (let i = 0, j = 0; i < n; i++) {
if (set.has(str[i])) {
res = Math.max(res, set.size);
while (j < n && str[j] !== str[i]) {
set.delete(str[j++]);
}
j++;
} else {
set.add(str[i]);
}
}
res = Math.max(res, set.size);
return res;
}