C++ 查找输入编号以了解其在数组中的位置
C++ 查找输入编号以了解其在数组中的位置,c++,arrays,algorithm,search,C++,Arrays,Algorithm,Search,我有一个小的算法问题。例如,我有一个数组 array[10] = {23,54,10,63,52,36,41,7,20,22}; 现在给定一个输入号,例如189,我想知道它应该位于哪个插槽中。 例如,该输入应该位于数组中的4个索引中,因为 23+54+10+63 = 150 and if we add 52 then sum will be 202 which will cover the range where 189 should lie. so the answer should be
我有一个小的算法问题。例如,我有一个数组
array[10] = {23,54,10,63,52,36,41,7,20,22};
现在给定一个输入号,例如189,我想知道它应该位于哪个插槽中。
例如,该输入应该位于数组中的4个索引中,因为
23+54+10+63 = 150 and if we add 52 then sum will be 202 which will cover the range where 189 should lie. so the answer should be 4.
我想找到一个摊销常数时间算法,可能在第一步我们对数组做一些预赋值,这样我们可以在常数时间内得到所有下一个查询。
输入数字将始终介于1和数组中所有项之和之间
感谢自然的解决方案是首先构建一个具有累积和的数组。这看起来像
sums[10] = {23,77,87,...}
然后使用二进制搜索(如下限算法)查找插入位置。那将是O(log(n))
。假设您的插槽数量不变,此解决方案也是时间常数。但我猜您希望在插槽数量方面的查找是O(1)
。在这种情况下,您必须创建一个完整的查找表。由于这些数字的规模相对较小,这是完全可行的:
int lookup[N];
for(i=0,j=0;i<10;i++)
for(k=0;k<sums[i];k++,j++)
lookup[j]=i;
int查找[N];
对于(i=0,j=0;i我认为你能得到的最好方法是使用累积数组,并通过使用二进制搜索以对数时间运行。我不确定是否存在一个具有常数时间的解决方案。你确定有一个吗?如果你真的需要常数时间,请创建第二个数组,该数组的大小是包含索引的最大和值e原始数组。因此,新数组[189]=4;如果您知道该数字始终在1和数组中所有项的总和之间,那么简单的常数时间算法是构建一个[1..sum]的数组,每个项包含每个数字的适当槽位。构建数组(只需执行一次)是O(N),然后查找是O(1)
当然,这假设您有足够的内存来存储阵列
除此之外,我认为您能做的最好的事情是对总和使用二进制搜索O(log(N))
输入的数字将始终在1和所有数字之和之间
数组中的条目
inttotal(0),i(0);
对于(;总计<输入值;++i)
{
总数+=数组[i];
}
//你的答案是i-1
无论是插槽计算还是项目插入,您都不会获得摊销固定时间。据我所知。您是否希望获得摊销固定时间?我不确定是否存在摊销固定时间。但我真的很感兴趣,这就是为什么社区成员会问到摊销固定时间的原因。我认为它不存在。因为您将有一个具有“洞”,你需要在这个数组中搜索才能找到你的位置。这个搜索不能在O(1)中完成。对此稍作修改,你可以使用一个数组,它包含的元素数与数组中所有值的总和相同(在本例中为328)。数组中每个项的值对应于数组槽…lookup[189]
和lookup[200]
的值都是4
。但是,这将受到数组中值总和的严格限制……但是对于OP的示例,它将作为O(1)工作查起来很容易。@Rook:我想这正是我在这里做的。嗯。我可以发誓,当我在回复中键入时,你答案的第二部分不在那里……就像O(log(b))
语句一样。可能我疯了。我想大多数人对O(logn)的看法是正确的时间算法。对于固定的时间,我需要更多的内存。然而,这是可行的,运行时间取决于数字。他正在寻找一个更有效的算法。@jim我想到添加“int-answer(i);For(;i
int total(0), i(0);
for(;total < inputValue; ++i)
{
total += array[i];
}
//your answer is i-1