1. 题目描述
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
2. 解题思路
这个题目可以使用双指针+map来实现:
- 首先用双指针维护一个滑动窗口用来剪切子串
- 开始时,两个指针都在起始位置,不断移动右指针,遇到重复的字符,就将左指针向后移动一位
- 右指针每次移动,都计算出两个指针之间的字符个数,并返回最大值
- 每次右指针移动还需要将右指针的索引和值存在Map中,便于后面遇到重复值时让左指针进行移动
需要注意的是,在左指针移动之后,map中还存在其之前的值,所以还要限制map中已经存在的值的索引要大于左指针的索引,也就是必须处于两指针之间的滑动窗口。
该算法的时间复杂度为O(n),空间复杂度为O(m),其中m是最长子串的长度。
3. 代码实现
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function(s) {
let res = 0
let map = {}
for(let left = 0, right = 0; right < s.length; right++){
const char = s[right]
if(map[char] >= 0 && map[char] >= left){
left = map[char] + 1
}
res = Math.max(res, right - left + 1)
map[char] = right
}
return res
};