题目描述
给定一个字符串
s
,请你找出其中不含有重复字符的 最长子串 的长度。示例 1:输入: s = "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是
"abc"
,所以其长度为 3。示例 2:输入: s = "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是
"b"
,所以其长度为 1。示例 3:输入: s = "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是
"wke"
,所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke"
是一个子序列,不是子串。提示:
0 <= s.length <= 5 *
s
由英文字母、数字、符号和空格组成
解题思路
为了解决这个问题,可以使用滑动窗口的技术。滑动窗口可以动态地维护一个子串,并且当发现子串中有重复字符时,可以调整窗口的起始位置,从而找到不含重复字符的最长子串。
具体步骤如下:
-
初始化:使用一个哈希集
set
来存储当前窗口内的字符。使用两个指针left
和right
表示滑动窗口的左右边界。初始时,left
和right
都指向字符串的起始位置。 -
移动窗口:当
right
指针所指向的字符未出现在set
中时,将其加入set
,并将right
右移,以扩大窗口;当right
指针所指向的字符已经在set
中时,说明出现了重复字符,这时需要将left
指针右移,缩小窗口,直到窗口内没有重复字符为止。 -
记录最大长度:每次更新窗口后,记录当前窗口的长度,并与已知的最大长度进行比较,保留较大的值。
-
终止条件:当
right
指针遍历到字符串的末尾时,遍历结束。
复杂度分析
-
时间复杂度:O(n)。每个字符在最坏情况下会被访问两次:一次通过
right
指针,一次通过left
指针。因此,总的时间复杂度为 O(n),其中n
是字符串的长度。 -
空间复杂度:O(min(m, n))。使用了一个哈希集来存储当前窗口内的字符,最坏情况下需要存储所有字符,因此空间复杂度与字符集大小
m
和字符串长度n
有关,取其中的较小值。
代码实现
package org.zyf.javabasic.letcode.hot100.slidingwindow;
import java.util.HashSet;
import java.util.Set;
/**
* @program: zyfboot-javabasic
* @description: 无重复字符的最长子串
* @author: zhangyanfeng
* @create: 2024-08-21 21:18
**/
public class LengthOfLongestSubstringSolution {
public int lengthOfLongestSubstring(String s) {
// 使用哈希集来存储当前窗口内的字符
Set<Character> set = new HashSet<>();
// 初始化左右指针和最大长度
int left = 0, right = 0;
int maxLength = 0;
// 开始滑动窗口遍历字符串
while (right < s.length()) {
// 如果当前字符不在哈希集中,说明没有重复,加入哈希集并移动右指针
if (!set.contains(s.charAt(right))) {
set.add(s.charAt(right));
right++;
// 更新最大长度
maxLength = Math.max(maxLength, right - left);
} else {
// 如果当前字符已经在哈希集中,说明有重复,移除左指针的字符并移动左指针
set.remove(s.charAt(left));
left++;
}
}
// 返回记录的最大长度
return maxLength;
}
public static void main(String[] args) {
LengthOfLongestSubstringSolution solution = new LengthOfLongestSubstringSolution();
// 测试用例 1
String s1 = "abcabcbb";
System.out.println(solution.lengthOfLongestSubstring(s1)); // 输出: 3
// 测试用例 2
String s2 = "bbbbb";
System.out.println(solution.lengthOfLongestSubstring(s2)); // 输出: 1
// 测试用例 3
String s3 = "pwwkew";
System.out.println(solution.lengthOfLongestSubstring(s3)); // 输出: 3
}
}
具体可参考:https://zyfcodes.blog.csdn.net/article/details/141401712