题目描述
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例3:
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
解题思路
暴力解决
- 从n位置开始向后遍历,n初始值为0,最长字串长度为len
- 字符逐个存入哈希表
- 当前不重复字符数m++
- 当字符在哈希表中已存在时,将m与len比较,若m>len,将m赋值给len
- 清空哈希表
- 从n+1处开始继续遍历
- 遍历循环结束,len即为最长子串长度
时间复杂度为O(n^2)
KMP
- 从n位置开始向后遍历,n初始值为0,当前子串初始位置m为0,当前子串长度len为0,最长字串长度为len_max
- 字符逐个存入哈希表,字符为key,字符在字符串中位置为value,len++
- 当字符在哈希表中存在且value值非负,将m的值修改为value_old + 1
- 修改value值为n
- 将字典中str[m]到str[value_old-1]的key对应的值都修改为-1,len–
- 将len与len_max比较,若len>len_max,将len赋值给len_max
- 继续从n+1处遍历
时间复杂度为O(n)
解题算法
C++
class Solution {
public:
int lengthOfLongestSubstring(string s) {
map<int,int> words;
map<int,int>::iterator iter;
int len_max = 0;
int pos_start = 0;
int len = 0;
for(int n = 0;n < s.length();n++)
{
iter = words.find(s[n]);
if(iter == words.end() || iter->second == -1)
{
words[s[n]] = n;
len ++;
}
else
{
int pos_old = iter->second;
iter->second = n;
for(int j = pos_start;j<pos_old;j++)
{
iter = words.find(s[j]);
iter->second = -1;
len --;
}
pos_start = pos_old + 1;
}
len_max = len > len_max?len:len_max;
}
return len_max;
}
};
Python3
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
n,len_max,pos_start,len_now = 0,0,0,0
words = {}
for n in range(len(s)):
i = words.get(s[n])
if i is None or i == -1:
words[s[n]] = n
len_now += 1
else:
words[s[n]] = n
for j in range(pos_start,i):
words[s[j]] = -1
len_now -= 1
pos_start = i + 1
len_max = max(len_max,len_now)
return len_max
滑动窗口
- 建立一个空的字典,当前子串长度len为0,最长不重复字符数max为0
- 遍历字符串,如果当前字符不在字典中或不在当前不重复子串中len +1
- 如果存在则len长度减少重复字符在子串位置
- 将字典中key为str[n]的值修改为n
- 如果len大于max则把len赋值给max
- 遍历结束返回max
时间复杂度为O(n)
解题算法
C++
class Solution {
public:
int lengthOfLongestSubstring(string s) {
map<int,int> words;
map<int,int>::iterator iter;
int len_max = 0;
int len = 0;
for(int n = 0;n < s.length();n++)
{
iter = words.find(s[n]);
if(iter == words.end() || iter->second < n - len)
{
len ++;
}
else
{
len = n - iter->second;
}
words[s[n]] = n;
len_max = len > len_max?len:len_max;
}
return len_max;
}
};
Python3
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
word = {}
num = 0
ret = 0
for i in range(len(s)):
pos = word.get(s[i])
if pos == None or pos < i - num:
num += 1
else:
num = i - pos
word[s[i]] = i
ret = max(ret,num)
return ret