题目:
给定一个字符串 s
,请你找出其中不含有重复字符的 最长子串 的长度。
示例 :
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
一,滑动双指针
如图:
代码:
public static int lengthOfLongestSubstring(String s) {
int length = s.length();
if (length == 1) {
return 1;
}
if (length == 0) {
return 0;
}
Set<Character> characterSet = new HashSet();
//末尾指针
int end = -1;
int max = 0;
//从开始指针进行遍历
for (int start = 0; start < length; start++) {
// 如果,set集合不包含end+1指针所在的字符,再将end+1的字符加入set,并将指针end+1+1后移,则窗口增大
//当start加1后,并且删除Set中start指针所在的字符,再判断end+1+1所在字符是否包含在set里,如果包含,再将start+1,则窗口在缩小。
while (end + 1 <= length - 1 && !characterSet.contains(s.charAt(end + 1))) {
characterSet.add(s.charAt(end + 1));
++end;
}
//当末尾指针,指在字符串尾部,这时,之后的字串肯定是越来越小,直接返回,
if (end == length - 1) {
max = Math.max(max, end - start + 1);
return max;
}
max = Math.max(max, end - start + 1);
//删除Set中start指针所在的字符
characterSet.remove(s.charAt(start));
}
return max;
}
解释:
新建一个set用于存放不重复的字符,set集合不包含end+1指针所在的字符,再将end+1指针所在字符加入set,并将指针end+1(后移),则窗口增大,直到set集合包含end+1指针所在的字符。随后求出最大子串,删除set中start指针所在的字符,start加1(指针后移),再判断end+1指针所在字符是否包含在set里,如果包含,删除Set中start指针所在的字符,再将start+1,则窗口在缩小,直到set集合里不包含end+1指针所在字符,接着就是移动end指针,不断窗口后移,找最长子串,直到end指向字符串尾端。
二,暴力双指针:
代码:
public static int lengthOfLongestSubstring(String s) {
int length = s.length();
//当长度为1则返回1
if (length == 1) {
return 1;
}
//当长度为0,直接返回0
if (length == 0) {
return 0;
}
//用于存储不重复的字符串
Set<Character> characterSet = new HashSet();
//末尾指针
int end = 0;
//最大子串
int max = 0;
//从开始指针进行遍历
for (int start = 0; start < length; start++) {
//当末尾指针小于等于字符长度,并且set集合不包含该字符,则加入set,并且将指针后移,直到出现重复字符
while (end <= length - 1 && !characterSet.contains(s.charAt(end))) {
characterSet.add(s.charAt(end));
end++;
}
//当末尾指针,指在字符串尾部,这时,之后的字串肯定是越来越小,直接返回,
if (end >= length - 1) {
return max = Math.max(max, end - start);
}
//end-start ,表明包含开始指针,不包含末尾指针,因为上面是将末尾指针加1再去判断是不是重复字符
max = Math.max(max, end - start);
//将set清零
characterSet.clear();
//将末尾指针指向开始指针,因为for循环结束,start+1,所以,end=start+1,重新循环,判读无重复字符的字串的长度
end = start + 1;
}
return max;
}
解释:
从start进行遍历,当end指针所在字符,不包含在set集合里面, 将end指针所在字符,加入set集合里面,将end+1(指针后移),直到set集合包含end指针包含所在字符,如果end指针指向字符末端,或者超过字符长度,则直接返回最大字符。当end指针不指向末尾,求出最大子串,再将set集合清空,将end指针指向start指针,继续从start开始遍历找最大子串