经典方法滑动窗口:(两个指针)
针对这个题我们首先假定两个指针 left 和 right 分别指在数组最左端.
然后两个变量记录长度length和maxlength.
并且因为不能有重复的字符,我们使用HashSet结构来当收集结果的表.
随着右指针不断往右移,左指针和右指针之间的就为截取的字符,而这个区域我们可以称之为"窗口"
下面举个例子:
以右指针为条件向右遍历,最开始指向的是a,我们把a取出来放到表中,这时length加一,maxlength也加一.
然后右指针移动,同理,遍历到b也加到表中,length加一,maxlength也加一
c也如此.
而当我们右指针再次遍历到b这个字符时,因为Set中已经有这个字符了我们就要让左指针移动,来实现不重复的字符,也就是"滑动的窗口"此时移动之前的左右指针之间的字符为abc.
而当左指针移动时,左右指针的字符为bc,我们把表中a字符删去,右指针判断表中还有b,自己还不能加,所以左指针继续遍历.
因为左指针遍历到的是b,此时表中的字符为bc,我们把b删去,length也要减一,但max的不变.而右指针看到表中已经有b,所以左指针继续遍历,到下一个
此时表中只c而ab都没有了,右指针看到b没有了,就可以把b加到表中,
这个时候表中为bc,length可以加1,.然后右指针继续遍历.
后面所有过程都和上述一样.
右指针遍历到d,左指针到第二个b时,此时最大
但是右指针还要继续遍历,直到遍历完整个字符.
此时遍历条件结束,我们就可以返回最大的无重复字符子串.
代码如下:
class Solution {
public int lengthOfLongestSubstring(String s) {
// 哈希集合,记录每个字符是否出现过
Set<Character> set = new HashSet<>();
int left = 0;
int maxLength = 0;
int right = 0;
while(right < s.length()) {
char currentChar = s.charAt(right);
// 如果当前字符已经在集合中,移动左指针直到移除该字符
while (set.contains(currentChar)) {
set.remove(s.charAt(left));
left++;
}
// 将当前字符加入集合
set.add(currentChar);
// 更新最大长度
maxLength = Math.max(maxLength, right - left + 1);//当前左右指针截取的字符长度和最大的比较
//右指针右移
right++;
}
return maxLength;
}
}
注意这里使用CharAt方法来截取每个字符,传入的值是字符在字符串的的下标.
结束.