3. 无重复字符的最长子串
给定一个字符串 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
由英文字母、数字、符号和空格组成
暴力遍历法
起始点可能是任何位置,那就从头遍历字符串,确定起始位置,然后接着遍历后面的字符串,取到不重复的子串,然后比较,留下最长的子串。
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function(s) {
// 边界处理
if (s === '') {
return 0;
}
if (s && s.length === 1) {
return 1;
}
// 暴力拆解
let arr = s.split('');
let res = ''; // 保留当前最长子串
let cur = []; // 当前无重复子串数组
for (let i = 0; i < arr.length - 1; i++) {
cur = [];
cur.push(arr[i]);
for (let j = i + 1; j < arr.length; j++) {
if (cur.indexOf(arr[j]) === -1) {
cur.push(arr[j]);
} else {
break;
}
}
if (cur.length > res.length) {
res = cur.join('');
}
}
return res.length;
};
优化
- 暴力遍历方法中,可以发现有些字符串内判断是否有重复字符操作重复了
- 如何去掉重复判断,可以使用滑动窗口的方法,保证无重复子串,滑动窗口记录窗口最大值 滑动窗口
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function(s) {
// 边界处理
if (s === '') {
return 0;
}
if (s && s.length === 1) {
return 1;
}
// 滑动窗口
let left, right;
left = right = 0;
let maxLength = 1;
let arr = s.split('');
let cur = [arr[0]];
while (right < arr.length - 1) {
// console.log(cur)
right++;
if (!cur.includes(arr[right])) {
// 没有相同元素,扩大滑动窗口
cur.push(arr[right]);
// console.log(cur)
if (cur.length > maxLength) {
maxLength = cur.length;
}
} else {
// 有相同元素,剔除前面的
cur = cur.slice(cur.indexOf(arr[right]) + 1);
cur.push(arr[right]);
}
}
return maxLength;
};