无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
代码:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int i=0,result=0;
for(int j = 0;j<(int)s.size();j++)
{
for(int k = i;k<j;k++)//k从i开始是因为已经发现i之前存在重复字符
{
if(s[k]==s[j])
{
i = k+1;
break;
}
}
if(j-i+1 > result)
{
result = j-i+1;
}
}
return result;
}
};
分析:
以“pwwkew”为例分析结果如下:
顺序\变量 | 变量 j | 变量 k | 变量 i | 变量 result |
---|---|---|---|---|
1 | 0 | 0 | 0 | 0 |
2 | 1 | 1 | 0 | 0 |
3 | 2 | 1 | 2 | 1 |
4 | 3 | 2 | 2 | 1 |
5 | 3 | 2 | 2 | 1 |
6 | 4 | 2 | 2 | 1 |
7 | 4 | 3 | 2 | 1 |
8 | 5 | 2 | 3 | 3 |
思想:
判断前j个元素是否有相同的,如果遇到相同的例如位于k位置(k<j),那么以后前k个元素(包括第k个,接下来从k+1开始)就不再遍历,因为第k个元素和第j个元素冲突(相同),然后j++继续判断。
扩展:KMP — 字符串匹配问题:(参考:https://blog.csdn.net/gao506440410/article/details/81812163)
#include <bits/stdc++.h>
using namespace std;
int next[1000]; //next数组
string str = "abcabcbb"; //文本串
string p_true = "bb"; //模式串1
string p_false = "ggg"; //模式串2
void GetNext(string p,int next[])
{
next[0] = -1;
int k = -1;
int j = 0;
while (j < (int)p.size() - 1)
{
//p[k]表示前缀,p[j]表示后缀
if (k == -1 || p[j] == p[k])
{
k++;j++;
next[j] = k;
}
else
{
k = next[k];
}
}
}
int KmpSearch(string s, string p)
{
int i = 0,j = 0;
while (i < (int)s.size() && j < (int)p.size())
{
//①如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++
if (j == -1 || s[i] == p[j])
{
i++;j++;
}
else
{
//②如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]
//next[j]即为j所对应的next值
j = next[j];
}
}
if (j == (int)p.size())
return i - j;
else
return -1;
}
int main()
{
GetNext(str,next);
cout << KmpSearch(str,p_true) << endl;
cout << KmpSearch(str,p_false) << endl;
return 0;
}
结果:
6
-1