题目详情
给定一个字符串s
,请你找出其中不含有重复字符的 最长子串 的长度。
示例1:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是"abc",所以其长度为 3。
示例2:
输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是"b",所以其长度为 1。
示例3:
输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是"wke",所以其长度为 3。
提示:
- 0 <= s.length <= 5 * 104
s
由英文字母、数字、符号和空格组成
题解
方法一:暴力解法
思路
遍历字符串的每一位,直到遇到重复的值结束。
实现
function lengthOfLongestSubstring(s) {
let length = 0;
const sList = s.split("");
if (sList.length <= 1) {
return sList.length;
}
let arr = [];
for (let i = 0; i < sList.length - 1; i++) {
arr = [sList[i]];
for (let j = i + 1; j < sList.length; j++) {
if (arr.includes(sList[j])) {
break;
} else {
arr.push(sList[j]);
}
}
length = Math.max(length, arr.length);
}
return length;
}
复杂度分析
- 时间复杂度:O(N2)。
- 空间复杂度:O(1)。
方法二:滑动窗口
思路
- 定义两个指针,不重复子串的开始位置为
start
,结束位置为end
。 - 定义一个map,如果
end
指向的字符map中不存在则存入map,key
为字符,value
为end + 1
,表示从他后面一位开始不重复;如果存在则更新start
的值,取start
和value
中的最大值,再更新value
的值。 - 定义变量
length
表示最长子串长度,当前子串长度为:end - start + 1
,我们需要取length
和end - start + 1
中的最大值赋值给length
滑动窗口
实现
function lengthOfLongestSubstring(s) {
let length = 0;
const sList = s.split("");
if (sList.length <= 1) {
return sList.length;
}
let start = 0;
let end = 0;
let map = new Map();
while (end < sList.length) {
let index = map.get(sList[end]);
// map中有值
if (index) {
start = Math.max(index, start);
}
length = Math.max(length, end - start + 1);
map.set(sList[end], end + 1);
end++;
}
return length;
}
复杂度分析
- 时间复杂度:O(N)。