3. [✔][M]无重复字符的最长子串
给定一个字符串 s
,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
提示:
0 <= s.length <= 5 * 104
s
由英文字母、数字、符号和空格组成
题解:
双指针、快慢指针、hash map、滑动窗口。
滑动窗口问题,使用快慢指针,一前一后判断窗口扩大还是缩小。核心难点就在于窗口是扩大还是缩小的判断上。
/*
* @lc app=leetcode.cn id=3 lang=typescript
*
* [3] 无重复字符的最长子串
*/
// @lc code=start
function lengthOfLongestSubstring(s: string): number {
let win = new Map();//窗口字符计数器
let left = 0;//左指针
let right = 0;//右指针
let len = 0;//最长子串
while (right < s.length) {//没有到s末尾,一直执行循环
let c = s[right];//最右边字符
right++;//窗口扩大
win.set(c, (win.get(c) || 0) + 1);//窗口中增加一个right位置字符
while (win.get(c) > 1) {//窗口中已经有增加的字符了,继续循环,直到win中这个字符只有1次
let d = s[left];//left位置字符
left++;//窗口缩小
win.set(d, (win.get(d) || 0) - 1);//减掉1次字符数量
}
len = Math.max(len, right - left);//结果在最大值和当前计算的字符长度之间取最大值
}
return len;
};
// @lc code=end