JavaScript LeetCode003

98 阅读2分钟

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: s = "abcabcbb"

输出: 3

解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

思路:

1、遍历字符串

2、遍历的同时处理记录子串及相应的逻辑,应该怎么进行标记呢?

声明三个变量i,j,max

i用于记录当前子串的起点

j用于记录当前子串的终点

maxLength为当前最长的子串长度

声明一个容器,这边用set方便比较重复字符。

刚开始时当前子串起点和终点处于同一位置 i=j=0。

然后终点j往后移动一个位置,判断此时j位置的值子串里面是否存在:

存在的话: 统计当前子串的长度,对比当前maxLength的值,谁大取谁的值。然后起点位置i需要移动到子串里重复的值的后一个位置。如图:子串中存在j位置的值7,那么起点i位置应该移动到标记新起点的位置,即重复值7后一位。然后j继续往后移动,不断重复比较直到j移动到最后一个字符。

不存在的话: j往下移动一个位置,再按此规则继续重复比较

下面是具体代码实现:

function  lengthOfLongestSubstring2 = function(s){
    let i = j = 0, //标记起点终点位置
        set = new Set(), //存储当前子串的容器,用于比较是否重复
	maxLength = 0; // 存储字符串子串的最长长度
	for(; j < s.length; j++){
		// 当前set存储的子串是否含有j位置的字符
		if(set.has(s[j])){
			//存在重复的字符的话
			maxLength = Math.max(maxLength, set.size) //存储子串最大长度 
			while(set.has(s[j])){
				set.delete(s[i]) // 更新当前子串直到删除掉重复字符
				i++ // i不断往后移动,直到重复值的下一个位置即可跳出循环
			}
		}
		// 将j位置值存入set,等待j++进行下一次比较
		set.add(s[j])
	}
	// 循环结束后还需比较最后一次容器存储的子串的长度(容易忽略)
	maxLength = Math.max(maxLength, set.size)
	return maxLength
}