题目
- 地址:3. 无重复字符的最长子串
- 给定一个字符串
s,请你找出其中不含有重复字符的 最长子串 的长度
思路
- 既然是子串,那么就存在
左边界和右边界,这里用left表示左边界的下标、right表示右边界的下标 - 以
abcabcbb为例,看下不同左边界的情况下,对应的最长串是多少- abcabcbb
- abcabcbb
- abcabcbb
- abcabcbb
- abcabcbb
- abcabcbb
- abcabcbb
- abcabcbb
- 像不像一个蠕动的毛毛虫,右侧是毛毛虫的头,左侧是毛毛虫的尾,如果头遇到了和尾相同的,就开始缩尾巴。比如
-
abcabcbb -> abcabcbb 是头部遇到了
a和尾巴的a相同,开始收尾巴,就变成了以b为尾巴(abcabcbb),然后头继续往前走,就变成了abcabcbb
-
- 假设上面的毛毛虫例子很抽象,或者不明白为什么是毛毛虫。重新梳理,还是以上面的abcabcbb -> abcabcbb 为例
- abcabcbb:当前情况下是满足左边距
left最长的情况。left下标就结束了。不可能再长了。此时右边距是right - 在此情况下,就去看
left + 1为左边距的情况,而且可以肯定的是,left + 1 到right是100%满足不重复的 - 在上面这个情况下,就固定了left + 1下标的左边距,右边距继续往右走,以此循环,直到左边距到最后
- abcabcbb:当前情况下是满足左边距
题解
var lengthOfLongestSubstring = function(s) {
let max = 0; // 最大的长度,返回值
const arr = []; // 用于存储left 到right之间的值
let right = 0; // 右侧下标
for (var left = 0; left<s.length;left++){ // 左边距从0开始
arr.shift(); // 只要left左边距往右走一步,就要把第一位去掉,进入下一次循环
while(right < s.length && !arr.includes(s[right])) { // 右边距往后走,如果没有重复的,放到arr中
arr.push(s[right])
right++ // 右坐标往后走
}
max = Math.max(arr.length, max) // 保存最大值
}
return max;
}