如何在恒定时间内完成此功能?

时间:2012-07-30 15:13:08

标签: c# time-complexity

我需要找到这个无限系列的第n个项:1,2,2,3,3,3,4,4,4,4 ......

你能为我这个任务给我一个恒定的时间函数吗?

int i = 1;
while(true)
{
   if(i = n)
      //do things and exit the loop

   i++;
}

我认为这不会是一个恒定的时间函数......

3 个答案:

答案 0 :(得分:3)

修改

在阅读了更多评论后,我似乎误解了这个问题。

如果你想在n位置找到一个数组的项目,那么答案是微不足道的:x[n],因为数组访问是恒定的时间。但是,如果由于某种原因你使用了一些访问时间不恒定的容器(例如链表),或者不想在数组中查找值,你必须使用arithmetic series公式来查找答案。

算术系列告诉我们n唯一项的位置i将是

n = i * (i - 1) / 2

所以我们只需要解决i。使用二次公式,并丢弃无意义的否定选项,我们得到:

i = Math.Floor( (1 + Math.Sqrt(1 + 8 * n)) / 2)

原始回复

我假设你正在寻找第n个唯一术语的位置,因为否则这个问题很简单。

听起来像第n个唯一词的第一次出现应该遵循arithmetic series。即第n个唯一术语的位置是:

n * (n - 1) / 2

答案 1 :(得分:2)

鉴于我对这个问题的理解,这更像是一个数学问题,而不是编程问题。

如果问题是:

鉴于一个无限系列,包括1份副本,2份副本3份,3份n ... n副本,这个系列中的第k个值是多少?

现在接近这个问题的第一个线索是在第一次出现n + 1之前有1 + 2 + 3 ... + n个值。具体地说,在n +之前有(前n个数的和)值1,或(n)(n-1)/ 2。

现在设置(n)(n-1)/ 2 = k。乘以并合理化为n ^ 2 - n - 2k = 0.使用二次方程求解,得到n =(1 + sqrt(1 + 8k))/ 2。这个楼层给出了之前有多少n个完整副本,并且幸运的是,给定基于零的索引,地板给出了数组中第k个点的值。

这意味着你在c#中的最终答案是

return (int) Math.Floor((1 + Math.Sqrt(1 + 8 * k)) / 2);

给定基于非零的索引,

return (int) Math.Floor((1 + Math.Sqrt(-7 + 8 * k)) / 2);

答案 2 :(得分:0)

        public static long Foo(long index)
        {
            if (index < 0)
            {
                throw new IndexOutOfRangeException();
            }

            long nowNum = 0;
            long nowIndex = 0;
            do
            {
                nowIndex += nowNum;
                nowNum++;
            } while (nowIndex < index);
            return nowNum;
        }