思路
- 重复字符涉及到关键词“重复,1次,出现次数”,这些情况一般可以考虑可以使用散列表,一般用字符作为键,次数或者索引作为值
- 涉及子串,可以考虑使用滑动窗口来动态的扩张收缩子串
- 设置一个rl指针,值动态的申明为遍历字符串的每一个i值索引,表示从当前i位置开始滑动窗口
- 设置一个rk指针,当rl在当前i位置的时候,rk不断++,直到rl和rk之间将要出现重复字符串
- 对于rl和rk之间的子字符保存,使用set数据的add和has方法保存和判断数据
- 对于遍历字符串的过程中,每次i+1,set集合中保存的第一个数据将被剔除,每次k++,set中从末尾追加一个数据。
- 考虑边界
- 字符串为空,maxLength应该为0;
题目
给定一个字符串 s ,请你找出其中不含有重复字符的 最长
子串
的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
提示:
0 <= s.length <= 5 * 104s由英文字母、数字、符号和空格组成
代码1(暴力求解 + 数组存储)
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function(s) {
let n = s.length;
let maxLen = 0;
let strArr = [];
for(let i = 0;i < n;i++){
if(strArr.includes(s[i])) {
maxLen = Math.max(maxLen,strArr.length);
strArr = [];
strArr.push(s[i]);
} else {
strArr.push(s[i]);
}
}
return maxLen;
};
代码2滑动窗口
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function(s) {
let n = s.length;
let occ = new Set()
let rk = 0;
let maxLen = 0;
for(let i = 0;i < n;++i) {
if(i != 0) {
occ.delete(s[i-1]);
}
while(!occ.has(s[rk]) && ((rk ) < n)) {
occ.add(s[rk],rk);
rk++;
}
maxLen = Math.max(maxLen,(rk - i));
}
return maxLen;
};