给定一个字符串,请找出其中字符的最长无重复子串。
例如,在”abcabcbb”中,其无重复字符的最长子字符串是”abc”,其长度为 3。
对于,”bbbbb”,其无重复字符的最长子字符串为”b”,长度为1。
解法一:
用一个map<char,int>
表示字符串中每个字符是否出现,初始化为0,表示未出现。
用两个指针分别指向字符串的第一个和第二个元素,用第二个指针从左往右扫描字符串。每扫描一个字符,根据数组中对应的值来判断这个字符是否已经出现。
如果没出现,则继续扫描,同时更新已知不相同子串的最大长度。
如果出现过,那么向右移动第一个指针,直到刚才重复的那个字符不再重复,然后继续上面的工作。
#include <iostream>
#include <string>
#include <map>
using namespace std;
class Solution {
public:
int lengthOfLongestSubstring(string s) {
map<char, int> m;
int i = 0, j = 1;
int len = 1, MAX = 0;
m[s[i]] = 1;
if(s.length()==1)
return len;
while(i<s.length() && j<s.length())
{
if(m[s[j]] == 0)
{
m[s[j]] = 1;
j++;
len++;
MAX = MAX>len?MAX:len;
}
else
{
m[s[i]] = 0;
i++;
len--;
}
}
return MAX;
}
};
int main()
{
Solution S;
int len = S.lengthOfLongestSubstring("a");
cout<<len<<endl;
return 0;
}
解法二:
分析:遍历该字符串,每遍历一个字母时,利用map去找该字母最近一次出现是什么时候,中间这一段便是无重复字符的字符串。时间复杂度O(n)。
class Solution {
public:
int lengthOfLongestSubstring(string s) {
map<char, int> m;
int start = 1, len = 0;
if(s.length()==1)
return len+1;
for(int i=1; i<=s.length(); i++)
{
if(m[s[i-1]] < start)
{
m[s[i-1]] = i;
len = len > (i-start+1) ? len : (i-start+1);
}
else
{
start = m[s[i-1]] + 1;
m[s[i-1]] = i;
}
}
return len;
}
};