【发布时间】:2014-08-23 17:21:31
【问题描述】:
我有一个仅由数字 0-9 组成的字符串。字符串的长度可以在 1 到 1,000,000 个字符之间。我需要在线性时间内找到字符串中不存在的最小数字。下面是一些例子:
1023456789 //Smallest number not in string is 11
1023479 //Smallest number not in string is 5
112131405678910 //Smallest number not in string is 15
大小为 1,000,000,我认为字符串中不存在的最小数字最多只能是 6 位。
我的方法是生成从 0 到 999,999 的所有数字,并将它们全部插入一个向量中(按顺序)。然后制作一张地图,标记已经看到的字符串。然后我遍历字符串,对于每个位置,我都得到从它开始的所有子字符串,大小为 1 到 6,并在地图中将所有这些子字符串标记为真。最后,我只是一个一个地检查所有键,当我在地图中找到第一个具有错误值的键时,我将其打印出来。
这里有一些代码sn-ps:
string tmp="0";
string numbers[999999];
void increase(int pos)
{
if(pos==-1)tmp.insert(0,"1");
else if(tmp.at(pos)!='9')tmp.at(pos)++;
else
{
tmp.at(pos)='0';
increase(pos-1);
}
}
//And later inside main
for(int j=0;j<999999;j++)
{
numbers[j]=tmp;
increase(tmp.size()-1);
}
for(int j=0;j<input.size();j++)
{
for(int k=0;k<6;k++)
{
string temp="";
if(j+k<input.size())
{
temp+=input.at(j+k);
appeared[temp]=true;
}
}
}
int counter=0;
while(appeared[numbers[counter]])counter++;
cout<<numbers[counter]<<endl;
关于算法第一部分的注释。我生成一次向量,然后将其用于 100 个字符串。我需要在 4 秒内解析所有 100 个字符串。
目前这个算法对我来说太慢了。我可以优化一些代码,还是应该考虑不同的方法?
【问题讨论】:
-
@A.Andevski,您是指与字符串长度相关的线性时间还是与子字符串数量(与字符串长度相关的二次方)相关的线性时间?我不确定前者是否可行。
-
这听起来像是来自竞赛的问题——请链接到它,以便我们知道它不是最新的。我可以想到一个算法,它在输入中的字符数加上答案的值是线性的。
-
我很想知道您是如何得出 170,000 的。
-
我明白了。 170,000 只是 1,000,000/6(大致四舍五入)。那可能很低。例如,假设字符串
"123456123"包含四个 6 位数字,只有 9 个数字。可能会想出一个非常接近该压缩比的安排。我怀疑你的最大值接近 500,000。 -
@JimMischel:见 de Bruijn 序列;对于任何大小为 k 的字母表和任何整数 n,您可以构造一个大小为 k^n 的循环,其中包含所有 k^n 个 n 字符序列。展开循环会产生一个长度为 k^n+n-1 的字符串,其第一个和最后一个 n-1 个字符相同。一个 1,000,000 位的序列只有 999,995 个 6 位子序列,因此至少有 5 个 6 位子序列不存在。特别是,一个 de Bruijn 序列(剪切而不是展开)将恰好具有相同数量的唯一子序列。
标签: c++ string algorithm substring