首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

第一题是找出字符串的最长不重复子串,输出长度解决思路

2012-05-09 
第一题是找出字符串的最长不重复子串,输出长度abcdefb就输出abcdefabcbef就输出cbef就说可以用hash实现,复

第一题是找出字符串的最长不重复子串,输出长度
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,
以此类推,在循环中记录最长的长度,以及最长的长度对应的起始位置就可以了

[解决办法]

探讨
如果只是由字母组成的字符串,定义一个长为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中用于记录字…

[解决办法]
感觉这道题有些类似于编程之美上的一道题。

就是,从字符串的末尾向前遍历;

由于单个字符也可以作为一个子串,
维持两个数组:Start[]和All[],
分别记录,从当前的字符为起始的子串的最长值,和当前字符后面的最长子串长度。

在向前遍历时,当有重复字符出现时,更新相应的长度值,
即,更新Start[curIndex]为从当前点,到那个已经存在的重复字符之前的长度;
All[curIndex]也要做相应调整。

比较:Max(Start[curIndex], All[curIndex]);

最后,第一个字符遍历完成后,就可以得到结果。

具体的那个比较的方法,还要再回去看看。
汗。。。
[解决办法]
探讨
感觉这道题有些类似于编程之美上的一道题。

就是,从字符串的末尾向前遍历;

由于单个字符也可以作为一个子串,
维持两个数组:Start[]和All[],
分别记录,从当前的字符为起始的子串的最长值,和当前字符后面的最长子串长度。

在向前遍历时,当有重复字符出现时,更新相应的长度值,
即,更新Start[curIndex]为从当前点,到那个已经存在的重复字符之前的长度;
All[curIndex]也要做相应调整。

比较:Ma…

热点排行