给定一个字符串,找出不含有重复字符的最长子串的长度。
示例: 给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度就是3。
给定 "bbbbb" ,最长的子串就是 "b" ,长度是1。
给定 "pwwkew" ,最长子串是 "wke" ,长度是3。请注意答案必须是一个子串,"pwke" 是 子序列 而不是子串。
思路:
- 从字符串第一个元素起,从左到右获取子串。
- 每前进一个字符(下标为j),就在当前子串中查找是否存在与当前字符重复的字符,如果存在(重复字符的下标为i),那么能确定一个包含不重复字符的子串,其长度为j - i 对比已存储的最大长度并把两者的最大值存储。
- 现在下一个子串的起点为当前重复的字符下标j.重复执行2、3操作,直到最后一个字符。
其实这是滑动窗口的思路。左闭右开。
int lengthOfLongestSubstring(char* s) {
int len = strlen(s);
//长度为0 的情况的处理
if(len == 0) return 0;
int max = 1;
int statrIndex = 0;
for (int i = 1; i < len; i ++) {
char subStr = s[i];
for(int j = statrIndex; j <i; j ++)
{
char ssubStr = s[j];
//如果找到重复字符串
if (subStr == ssubStr ) {
if (max < i - statrIndex) {
max = i - statrIndex;
}
statrIndex = j + 1;
break;
}
}
//长度没添加一位,更新最大值
if (max < i + 1 - statrIndex) {
max = i + 1 - statrIndex;
}
}
return max;
}
复制代码
其他解法:
//每个字符都有唯一字符串ASCII的作为唯一标识,这是个技巧性问题。最多256个
int lengthOfLongestSubstring(char* s) {
//算法:用book标记出现过的字符的index,用max标记最大长度,用start标记当前不重复开始的index,用num表示当前不重复的个数
//遍历数组,若book[]大于start,说明遇到相同元素,则从其相同处重新计算长度和起始位置
if(NULL == s)
return NULL;
int len=strlen(s);
int book[255]={0};
//memset(book,0xff,255*sizeof(int));//将book初始化为-1
if (0==len)
return 0;
int start=0,max=0;//max_start=0;
int num=0;
for (int i=0;i<len;i++)
{
if(book[s[i]]==0 || book[s[i]]<start+1)
{
num++;
if(num>max)
{
//max_start=start;
max=num;
}
book[s[i]]=i+1;
}
else
{
start=book[s[i]];
num=i-start+1;
book[s[i]]=i+1;
}
}
return max;
}
复制代码
//写得好屌啊
int lengthOfLongestSubstring(char* s) {
int len=0;
char *end=s,*temp;
char* addressTable[128]={NULL};
while(*end){
temp = addressTable[*end];
addressTable[*end]=end;
if(temp>=s){
len=end-s>len?end-s:len;
s = temp+1;
}end++;
}
len=end-s>len?end-s:len;
return len;
}
复制代码
小结:这里又存在查找问题,可以考虑使用哈希Map提高效率。
待完善....