假设有一个字符串“abcdebfgh”
那么最长不重复字串是"cdebfgh",长度是7
解题思路:
1、用一个二维数组 bits[26][2],存储每个字符ch('a'-'z')的信息。bits[ch-'a'][0]的值为0表示ch在字符串中还没有出现,为1表示已经出现过,bits[ch-'a'][1]存储字符ch在字符串中出现的位置;
2、maxLen记录最长不重复字串长度,初始为0;用start记录不重复字串(未必是最长的)的开始位置,left记录最长不重复字串的开始位置,right记录最长不重复字串的结束位置;
3、从字符串str中每读取一个字符ch,检测bits[ch-'a'][0]的值,是0,则该字符在字符串str中还没有出现过,bits[ch-'a'][0]置1,bits[ch-'a'][1]记录ch在str中的位置,不重复字串的长度加1,noRepeatSeqLen++;若是1,则检测到重复字符,start指向下一个字符的位置。若noRepeatSeqLen > maxLen,就maxLen = noRepeatSeqLen,left = start, right = 当前字符位置 - start;
4、重复第3步,直到最后一个字符;
5、第4步循环结束后,再判断最后一个的非重复字符串是否最长非重复字符串,既,若noRepeatSeqLen> maxLen,就maxLen =noRepeatSeqLen,left = start,right = 当前字符位置 -start。否则,直接返回maxLen。
/**求一个字符串的最长不重复字串
* 例如字符串 abcdebfgh,则最长字串是cdebfgh
* maxNoRepeatSeq(const char* str, int &left, int &right)
* 返回值:最长不重复字串长度
* left是最长不重复字串在原字符串中的开始位置
* right是最长不重复字串在原字符串中的结束位置
* 并输出最长不重复字符串
**/
#include <iostream>
using namespace std;
int maxNoRepeatSeq(const char* str, int &left, int &right)
{
char bits[26][2]={0};
int start = 0;
int curr_pos = 0;
int maxLen = 0;
int noRepeatSeqLen = 0;
while (*str)
{
int i = (int)(*str - 'a');
if (bits[i][0] == 0)//没有重复字符出现
{
bits[i][0] = 1;
bits[i][1] = curr_pos;
noRepeatSeqLen++;
}
else //出现了重复字符
{
if (noRepeatSeqLen > maxLen)
{
maxLen = noRepeatSeqLen;
left = start;
right = curr_pos - 1;
}
start = bits[i][1] + 1; //记录非重复子串(未必是最长的)的开始位置
bits[i][1] = curr_pos; //更新字符ch的位置信息
noRepeatSeqLen = curr_pos - start + 1;
for (int k=0; k<26; k++)//出现重复字符串后bits[i]要清零,再计算下一个串
{
bits[k][0] = 0;
}
}
curr_pos++;
str++;
}
if (noRepeatSeqLen > maxLen)
{
maxLen = noRepeatSeqLen;
left = start;
right = curr_pos - 1;
}
return maxLen;
}
int main()
{
const char* str = "abcdebfgh";//"abcdebfgh";
int left, right;
int len = maxNoRepeatSeq(str, left, right);
cout << "maxLen:"<< len <<" " << endl;
cout << "left:" << left << " right:" <<right<<endl;
for(int i=left; i<=right; i++)
{
cout<<*(str+i);
}
return 0;
}