无重复字符的最长子串
持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
一般解法:滑动窗口
题解
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function(s) {
let ans = 0
let rk = -1
let set = new Set()
for(let i=0; i<s.length; i++){
if(i !== 0){
set.delete(s[i-1])
}
while(rk + 1 < s.length && !set.has(s[rk + 1])){
set.add(s[rk+1])
rk++
}
ans = Math.max(ans, set.size)
}
return ans
};
思路
先从暴力解法入手
想得到答案,需要对比所有可能的结果
于是需要循环字符串s,以当前位置 index 为起点,计算每个位置的子串
使用数组记录当前位置的子串,循环位于 index 之后的字符,添加到数组中,直到出现数组中重复的字符。为了方便判断,数组可以优化为 set
最后比较所有的结果,得出最后的结果。这里不必存所有的结果,可以使用一个 ans 变量,只记录最大的结果即可
计算最长子串的过程可以使用滑动窗口优化
因为如果 index 0 的最长子串长度为 rk
那么,在计算 index 1 的最长子串时,是没有必要从 index 1 开始的
因为 index1 --> rk 这段在 index 0 时已经判断过,是必然不重复的。 所以,index 1 可以直接从 rk+1 开始判断
此时 index -> rk 就相当于窗口,窗口的大小在计算 index 位置的最长子串时不断增加,作为下一个位置 index+1 计算时优化的依据
- 难点1:rk 的初始值为 -1,也就是窗口最小为 -1
- 难点2:要记得每次循环开始时,把上一个字符从 set 中去掉(index 0 时除外)
Follow Up
一般公司对前端的算法要求,可能不会再追问了
如果要追问的话,最可能是,如果允许重复一次字符怎么办等等
可以参考 LeetCode 395 424 2024。。。