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

superspring 2009-07-26 10:23:53
abcdefb就输出abcdef
abcbef就输出cbef

就说可以用hash实现,复杂度是O(n)
请给我点思路,我要的不是代码,谢谢
...全文
4720 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
mogui369 2012-05-08
  • 打赏
  • 举报
回复
不错。
LeonTown 2009-07-30
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 LeonTown 的回复:]
感觉这道题有些类似于编程之美上的一道题。

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

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

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

比较:Ma…
[/Quote]

上述方法,
在每遍历一个节点时,更新方法似乎是:
若当前点不重复,Start[Cur] = 1+Start[Cur+1];
All[Cur] = Max(Start[Cur], All[Cur+1]);

若重复,
Start[Cur] = 到重复节点前的长度,可以通过hash辅助实现;
All[Cur] = Max(Start[Cur], All[Cur+1]);

最后,All[0]应该就是结果;
这里还要记录最长字串。

另外,对于bcdefb,最长字串有两种选择,
可能也会有问题。
LeonTown 2009-07-30
  • 打赏
  • 举报
回复
感觉这道题有些类似于编程之美上的一道题。

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

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

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

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

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

具体的那个比较的方法,还要再回去看看。
汗。。。
showjim 2009-07-29
  • 打赏
  • 举报
回复
        public static string maxSubstring(string bigString)
{
string value = bigString;
if (bigString != null && bigString.Length >1)
{
char stringChar;
Dictionary<char, int> charIndex = new Dictionary<char, int>();//记录字符起始位置
int length = bigString.Length, maxLength = 0, maxIndex = 0, startIndex = 0;
for (int charLength, i = 0; i < length; i++)
{
if (charIndex.ContainsKey(stringChar = bigString[i]))
{
if (charIndex[stringChar] >= startIndex)
{//发现重复字符
if ((charLength = i - startIndex) > maxLength)
{//修改最大子串起始位置
maxLength = charLength;
maxIndex = startIndex;
}
if ((startIndex = charIndex[stringChar] + 1) + maxLength >= length) break;//检测是否结束
}
charIndex[stringChar] = i;
}
else charIndex.Add(stringChar, i);
}
value = ((length -= startIndex) > maxLength ? bigString.Substring(startIndex) : bigString.Substring(maxIndex, maxLength));//比较最后串与已发现的最大串
}
return value;
}
LeonTown 2009-07-29
  • 打赏
  • 举报
回复
最简单的就是用stl中的map,
定义为map<char, unsigned int>,第一个参数为字符,第二个参数为在串中出现的下标。

遍历字符串的过程中,到map中查找,
出现过的字符就跳过,没出现过的就将其加入map。

输出时,可能需要根据,map中的第二个参数,按原序输出。
CoderPlusPlus 2009-07-29
  • 打赏
  • 举报
回复
直观地得到一个思路,表达起来真够难的,直接写代码要更容易

以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

重复以上过程
acdbxzyw 2009-07-29
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 CoderPlusPlus 的回复:]
直观地得到一个思路,表达起来真够难的,直接写代码要更容易

以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]] …
[/Quote]
顶。
j8daxue 2009-07-29
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 litaoye 的回复:]
如果只是由字母组成的字符串,定义一个长为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中用于记录字…
[/Quote]
貌似你这找的是最长重复子串
绿色夹克衫 2009-07-29
  • 打赏
  • 举报
回复
如果只是由字母组成的字符串,定义一个长为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,
以此类推,在循环中记录最长的长度,以及最长的长度对应的起始位置就可以了
spenny83feng 2009-07-29
  • 打赏
  • 举报
回复
#include <stdio.h>
using namespace std;

int main()

{
char szAry[1024] = {0};
memcpy( szAry, "abdfacdfhjkmnopqrstgggsfaadff", 29 );

int nLengths(0), nTmpLength(0), i(0);
int a[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;

}

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧