题目分析:
暴力破解,O(n^3)
动态规划 dp[i] = i - lastest_repeat(i) 即当前位置减去在此之前最后重复位置
leatest_repeat(i) = max({index}) {index}指重复出现的重复的下标
理解版O(3n)
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if (s.length() < 2) return s.length(); //length = 1 return 1; length = 0 return 0;
int is_appear[256];
int tag[s.length()];
memset(tag, -1, sizeof(int) * s.length());
memset(is_appear, -1, sizeof(int) * 256);
//找到s[i]在[0,i - 1]内之后最后出现的位置,并记录,如果没有出现,记录为-1
for (int i = 0; i < s.length(); i++)
{
char ch = s[i];
if (is_appear[ch] == -1)
{
is_appear[ch] = i;
}
else
{
tag[i] = is_appear[ch];
is_appear[ch] = i;
}
}
//求s[i]位置之前最后出现重复的位置,即tag[i] = max{tag[0], ..., tag[i - 1]};
int _max = -1;
for (int i = 0; i < s.length(); i++)
{
_max = max(_max, tag[i]);
tag[i] = _max;
}
_max = -1;
//当前位置-最后重复位置即为以s[i]结尾最长不重复子串的长度,边求边记录最大值
for (int i = 0; i < s.length(); i++)
{
_max = max(_max, i - tag[i]);
}
return _max;
}
};
简化版O(n)
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if (s.length() < 2) return s.length();
int is_appear[256];
int tag[s.length()];
memset(tag, -1, sizeof(int) * s.length());
memset(is_appear, -1, sizeof(int) * 256);
int _max = -1;
int res = -1;
for (int i = 0; i < s.length(); i++)
{
char ch = s[i];
if (is_appear[ch] == -1)
{
is_appear[ch] = i;
}
else
{
_max = max(_max, is_appear[ch]);
is_appear[ch] = i;
}
tag[i] = _max;
res = max(res, i -tag[i]);
}
return res;
}
};