给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
来源:力扣(LeetCode) 3. 无重复字符的最长子串
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
法一:(执行时间36ms)
int lengthOfLongestSubstring(char * s)
{
if(s == NULL) return 0;
int len = strlen(s);
char tmp[128] = ""; //用于检查是否与相同的元素
char *str = (char*)malloc(len+1);
int k = 0; //子串下标
int index = 0; //子串在母串中的起始下标
int max = 0; //子串长度
for(int i = 0; i < len; i++)
{
if(tmp[s[i]] == 1) //有相等元素
{
if(max < k)
{
max = k;
}
k = 0;
i = index++; //从s的第二个(第三个、第四个……)字符重新找子串
if(len-i <= max) return max;//如果剩余没有遍历的子串长度小于max直接return
memset(tmp,0,128);
continue;
}
tmp[s[i]] = 1; //从0号下标开始存a一直到52号下标存放Z
str[k++] = s[i];
}
if(max < k)
{
max = k;
}
return max;
}
法二:(来源于力扣、执行时间0ms)
int lengthOfLongestSubstring(char * s)
{
int flag[257];
int curlen, maxlen, i, slen;
slen = strlen(s);
if (slen <= 0)
return 0;
for (i = 0; i < 257; i++)
flag[i] = -1;
for (i = 0, curlen = 0, maxlen = 0; i < slen; i++)
{
if ((i - curlen) > flag[s[i]])
{
curlen++;
}
else
{
curlen = i - flag[s[i]];
}
flag[s[i]] = i;
//printf("s[i]=%c, curlen=%d, maxlen=%d, flag[%c]=%d\n", s[i], curlen, maxlen, s[i], flag[s[i]]);
if (maxlen < curlen)
maxlen = curlen;
}
return maxlen;
}
法三:(来源于力扣、执行时间4ms)
int lengthOfLongestSubstring(char * s)
{
int maxLen = 0;
int start = 0;
int end = 0;
int windowlen = 1;
int i = 0;
int strlenth = 0;
if (s == NULL)
{
return 0;
}
strlenth = strlen(s);
if (strlenth == 0 || strlenth == 1)
{
return strlenth;
}
while (s[end + 1] != 0)
{
for (i = start; i <= end; i++)
{
if (s[i] == s[end + 1])
{
break;
}
}
// 在原来串没找到重复,则end扩大,窗口扩大; 否则,左边边界移动到第一个重复字符之后
if (i <= end)
{
start = i + 1;
}
end++;
windowlen = end - start + 1;
if (maxLen < windowlen)
{ // 保存最大长度
maxLen = windowlen;
}
}
return maxLen;
}