第一题是找出字符串的最长不重复子串,输出长度
abcdefb就输出abcdef
abcbef就输出cbef
就说可以用hash实现,复杂度是O(n)
请给我点思路,我要的不是代码,谢谢
[解决办法]
直观地得到一个思路,表达起来真够难的,直接写代码要更容易
以abcbef这个串为例
用一个数据结构pos记录每个元素曾出现的下标,初始为-1
从s[0]开始,pos['a'] == -1,说明a还未出现过,令pos['a'] = 0,视为将a"加入当前串",同时长度++
同理令pos['b'] = 1,pos['c'] = 2
到s[3]时,pos['b'] != -1,说明'b'在前面已经出现过了,此时可得到一个不重复串"abc",刷新当前的最大长度,然后做如下处理:
pos[s[0~2]] = -1,亦即将"ab""移出当前串",同时当前长度减去3
重复以上过程
[解决办法]
最简单的就是用stl中的map,
定义为map<char, unsigned int>,第一个参数为字符,第二个参数为在串中出现的下标。
遍历字符串的过程中,到map中查找,
出现过的字符就跳过,没出现过的就将其加入map。
输出时,可能需要根据,map中的第二个参数,按原序输出。
[解决办法]
#include <stdio.h>
using namespace std;
int main()
{
charszAry[1024] = {0};
memcpy( szAry, "abdfacdfhjkmnopqrstgggsfaadff", 29 );
intnLengths(0), nTmpLength(0), i(0);
inta[256];
for ( i; i < 256; ++i )
{
a[i] = 0;
}
for ( i = 0; i < 29; ++i )
{
int k = (int)(szAry[i]);
if ( a[k] == 0 )
{
nTmpLength += 1;
a[k] = nTmpLength;
if ( nTmpLength > nLengths )
{
nLengths = nTmpLength;
}
}
else
{
a[k] = nTmpLength;
nTmpLength = 1;
}
}
printf( "nLengths: %d\n", nLengths );
return 1;
}
[解决办法]
如果只是由字母组成的字符串,定义一个长为26的数组做hash就可以,以abcbef为例
串的起始index为0(startIndex = 0),结束index也为0(endIndex = 0)
记录字符串上一次位置的值的数组,全部初始化为-1 (lastIndex int[26])
endIndex逐渐向后读入字符,
读入a,判断lastIndex中用于记录字符a的元素lastIndex[0]的值为-1,-1 < startIndex, 将lastIndex[0]设为1,此时字符串长度为1,
读入b,判断lastIndex中用于记录字符b的元素lastIndex[1]的值为-1,-1 < startIndex, 将lastIndex[1]设为2,此时字符串长度为2,
读入c,判断lastIndex中用于记录字符c的元素lastIndex[2]的值为-1,-1 < startIndex, 将lastIndex[2]设为3,此时字符串长度为3,
读入b,判断lastIndex中用于记录字符b的元素lastIndex[1]的值为2,2 > startIndex, 将startIndex 设为2 lastIndex[2]设为4,此时字符串长度为2,
以此类推,在循环中记录最长的长度,以及最长的长度对应的起始位置就可以了
[解决办法]