题目:
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列, 不是子串。
思路:
典型的滑动窗口问题,采用双指针的策略,不断记录左右指针之间的距离;详细步骤如下:
- 左右指针都初始化为0;初始化最长无重复字符串的长度为0;
- 右指针向右移动,判断右指针的元素是否与前面的元素重复:
- a. 不重复则继续向右滑动,记录左右指针之间字符串的长度,和初始化的长度对比,取最大值;
- b. 重复,左指针向右滑动,滑动过程中同时剔除元素,直到不存在与右指针指向字符相同的字符为止
- 将右指针指向的字符加入队列;
- 记录左右指针之间字符串的长度,和初始化的长度对比,取最大值;
如此循环,直到右指针指向字符串的最后一个字符;
代码:
详细代码和注释如下:
public static int lengthOfLongestSubstring(String s) {
//定义一个set用于进行元素判重
Set<Character> set = new HashSet<>();
//初始化长度以及左右指针
int len = 0;
int left = 0;
int right = 0;
//右指针不断向右滑动,直到字符串结束;过程中段记录最长子串的长度
while(right<s.length()){
//如果右指针的字符在当前set中存在,则滑动左指针,直到不存在为止,滑动过程中剔除相关元素
while(set.contains(s.charAt(right))){
set.remove(s.charAt(left));
left++;
}
//将当前字符加入到set集合中
set.add(s.charAt(right));
//计算截止目前最长的无重复字符的子串的长度
len = Math.max(len, right - left + 1);
right++;
}
return len;
}