本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
解题思路
思路一
我们先创建一个set,用来存放最长字符串,然后创建两个指针,left指向字符串开头,right随着for循环遍历字符串,for循环内部进行判断,如果set里面没有right指向的字符,则还没有重复的字符,将right指向字符添加到set中,更新最大子串的长度,也就是原来的result和现在的set大小进行比较,取最大值,如果set里面存在right指向的字符,则从set里删除left所指向的字符,缩小窗口,并且递增left,直到set里面没有right所指向的字符为止。这里需要注意的是缩小窗口需要使用while,不然只会执行一次,重复以上步骤,直到遍历完字符串
var lengthOfLongestSubstring = function(s) {
const set = new Set();
let result = 0, left = 0, right = 0;
for(;right < s.length; right++){
if(!set.has(s[right])){
set.add(s[right]);
result = Math.max(result,set.size);
}else{
while(set.has(s[right])){
set.delete(s[left]);
left++;
}
set.add(s[right])
}
}
return result;
};
思路二
var lengthOfLongestSubstring = function(s) {
// 字符长度 <= 1 直接返回
if (s.length <= 1) return s.length
// 定义一个变量来存长度
let max = 1
// 定义一个 map 存子字符串
let map = new Map()
// 循环遍历
for (let i = 0; i < s.length; i++) {
// map 里没有直接设
if (!map.has(s[i])) {
map.set(s[i], s[i])
// 判断一下 max 和 map.size 大小,把最大的给 max; (max = Math.max(max, map.size) 也可以)
max = map.size > max ? map.size : max
} else {
// 判断一下是否是连续重复出现,重复出现直接把map清除再设值
const prevStr = map.get(s[i - 1])
if (prevStr === s[i]) {
map.clear()
map.set(s[i], s[i])
max = max = map.size > max ? map.size : max
}
// 比如 12315689 1再次出现,第二个1之前的必须全部清除,因为是子串,不是子序列
let mapArr = Array.from(map.keys())
mapArr.slice(0, mapArr.lastIndexOf(s[i]) + 1).forEach(item => map.delete(item))
map.set(s[i], s[i])
max = map.size > max ? map.size : max
}
}
return max
};