思路:
(1)暴力遍历
class Solution {
public:
int lengthOfLongestSubstring(string s)
{
string result;
int max=0;
int remax = 0;
bool flag = false;
int len = s.size();
if (s[0] == ' '||s.size()==1)
{
remax = 1;
return remax;
}
else
{
for(int k =0;k<len;k++)
{
flag = false;
result.clear();
if(remax<max)
remax = max;
max = 0;
for (int i = k;i < len;i++)
{
max++;
if (i == k)
{
result.push_back(s[i]);
}
else
{
for (int j = 0;j < result.size();j++)
{
if (s[i] == result[j])
{
flag = true;
continue;
}
}
if (flag == true)
{
max = max - 1;
break;
}
else
result.push_back(s[i]);
}
}
}
}
return remax;
}
};
(2)滑动窗口
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int res = 0;
int len = s.size();
int freq[256] = {
0 };
int l = 0, r = -1;
while (l < len) {
if (r + 1 < len && freq[s[r + 1]] == 0) {
freq[s[++r]]++;
}
else {
freq[s[l++]]--;
}
res = max(res, r - l + 1);
}
return res;
}
};
在滑动窗口的代码中,如果我们遇到字符串为pwwkew因为有两个连续的W我们希望的是让左指针直接来的第二个W,根据代码我们可以先让左指针直接跨越右指针来到右边,再让右指针移动过去。
通过代码就是让左指针指的W的指变为-1,这样就可以让右指针指的对象的值不为0,继续移动。比较难理解。
(3)哈希表+滑动窗
核心的滑动窗的代码是不变的,但是我们需要思考如何将左指针指向那个重复的元素的下一个元素(这里真的很重要,不然会导致很多问题)。使用哈希表可以通过将左边的元素不停的消除来达到目的。
class Solution {
public:
int lengthOfLongestSubstring(string s) {
// 哈希集合,记录每个字符是否出现过
unordered_set<char> occ;
int n = s.size();
// 右指针,初始值为 -1,相当于我们在字符串的左边界的左侧,还没有开始移动
int rk = -1, ans = 0;
// 枚举左指针的位置,初始值隐性地表示为 -1
for (int i = 0; i < n; ++i) {
if (i != 0) {
// 左指针向右移动一格,移除一个字符
occ.erase(s[i - 1]);
}
while (rk + 1 < n && !occ.count(s[rk + 1])) {
// 不断地移动右指针
occ.insert(s[rk + 1]);
++rk;
}
// 第 i 到 rk 个字符是一个极长的无重复字符子串
ans = max(ans, rk - i + 1);
}
return ans;
}
};