一直以为这个方法是对的,后来发现这种方法是错误的,不能处理嵌套的情况,如"adercijckega",稍后再修正!
最近面试遇到这题,再网上参考了一些blog,自己归纳出方法并用C++实现。
问题:求出字符串中最长不重复的字符串,如“abccdefgchi”,最长不重复字符串为defgchi.
分析:
1.定义一个二维数组bit[26][2]:其中bit[ch - 'a'][0]为0表示字符ch还未出现过,bit[ch - 'a'][0]为1表示字符ch已经出现过了;bit[ch - 'a'][1]中保存的是字符ch在字符串中出现的位置。
MaxLen: 表示最长不重复字符串的长度;
begin: 标识不重复字符串的起点;
end: 标识不重复字符串的终点;
start: 当有重复字符出现,以此标识新的不重复字符串的起点;
StrLen: 不重复字符串的长度(这个不重复字符串不一定是最长的那个,它只是一个临时的不重复字符串),随字符串增加而增加;
2.从原字符串中逐个读取字符,如相应的bit[ch - 'a'][0]为0,表示未出现过此字符,则只需将bit[ch - 'a'][0]置1,并在StrLen加1;如果相应的bit[ch - 'a'][0]为1,说明已经出现过相同字符,判断此时不重复字符串是否比之前得到的最长不重复复字符更长,是的话将此字符串当做是最长不重复字符串,否则保留原来的最长不重复字符串;
3.重复第2步,直到字符串结尾;
4.判断最后一段不重复字符串是否比之前得到的最长不重复字符串更长,是的话将此字符串当做是最长不重复字符串,否则保留原来的最长不重复字符串;
时间复杂度:因为要对字符串中每个字符进行读取和比较,所以时间复杂度为O(n)。
程序粗略流程图如下:
#include <iostream>
int GetMaxNoRepStr(const char *str, int len);
void main(void)
{
char arr[] = "abccdefgchi";
int len = strlen(arr);
GetMaxNoRepStr(arr, len);
}
int GetMaxNoRepStr(const char *str, int len)
{
using namespace std;
//初始化一些变量
int bit[26][2] = {0}; //用来标识字符是否出现过,和出现的位置
int MaxLen = 0; //最长不重复字符串的长度
int begin = 0;//标识不重复字符串的起点
int end = 0;//标识不重复字符串的终点
int start = 0;//当有重复字符出现,以此标识新的不重复字符串的起点
int StrLen = 0;//不重复字符串的长度,随字符串增加而增加
int i, n;
const char *pStr = str;
//逐个字符读取并处理
for (i = 0; i < len; i ++)
{
n = pStr[i] - 'a';//得到字符在二维数组中的位置
if (bit[n][0] == 0)
{//之前没有相同字符出现
bit[n][0] = 1; //标识此字符已经出现过
bit[n][1] = i;//保存字符出现的位置
StrLen ++;
}
else
{//之前有相同字符出现过
if (StrLen > MaxLen)
{//替换之前的最长不重复字符串
begin = start;
end = i - 1;
MaxLen = StrLen;
}
else
{//保留之前的最长不重复字符串
//do nothing
}
StrLen = i - start; //设置新的不重复字符串的长度
start = bit[n][1] + 1; //不重复字符串的开始位置重置到此字符的下一个位置
bit[n][1] = i; //重复字符定位到新位置
}
}//end of for
//最后一段不重复字符串和之前的最长不重复字符串的比较
if (StrLen > MaxLen)
{
begin = start;
end = i - 1;
MaxLen = StrLen;
}
//打印最长不重复字符串
for (i = begin; i <= end; i ++)
{
cout << pStr[i] ;
}
cout << endl;
return MaxLen;
}