我正在阅读Cracking the Coding Interview(新的)。该程序似乎正在运行。当我检查出来时,似乎N ^ 2/2就是答案。我不认为我是对的。有人能告诉我Big-O是什么以及为什么?
class Program
{
static void Main(string[] args)
{
int userNumber = Convert.ToInt32(Console.ReadLine());
int[] makeAnArray = new int[userNumber];
for (var x = 0; x < userNumber; x++)
{
makeAnArray[x] = x;
}
DisplayIterations(makeAnArray);
}
static void DisplayIterations(int[] testA)
{
int totalIterations = 0;
for (var i = 0; i < testA.Length; i++)
{
totalIterations++;
Console.WriteLine("i is " + i );
for (var j = i + 1; j < testA.Length; j++)
{
totalIterations++;
Console.WriteLine("j is " + j);
}
}
Console.WriteLine("The amount of iterations: " + totalIterations);
}
}
基本上该函数接受一个数组,为数组长度运行for
循环,并为for循环length-1
运行。我输了10回到了55.
答案 0 :(得分:2)
实际迭代次数,其中n
是数组的大小,是:
n(n+1)/2
可以扩展到
(n^2 + n)/2
然而,在Big O表示法中,您通常对算法类感兴趣,因为输入大小变大,并且可以忽略两个常量(例如上面公式中的2)以及指数小于最大 - 因此您可以忽略n
组件,因为n^2
将非常非常快地超过非二次组件,因为n
的大小会增加。因此,您可以将实际操作计数为(n^2 + n)/ 2
的算法简称为O(n ^ 2)。
供参考,以下是来自Wikipedia的Big O表示法的定义:
Big O表示法是一种数学符号,用于描述当参数趋向特定值或无穷大时函数的限制行为。
解释为什么你有n(n + 1)/ 2次操作:
您正在以下列方式迭代您的数组:
for (var i = 0; i < arr.Length; i++)
{
for (var j = i + 1; j < arr.Length; j++)
{
}
}
我将用以下符号绘制一些示例:
i0 means that your program printed out 'i is 0'
j1 means that your program printed out 'j is 1'
让我们用数组长度为1绘制你的程序打印的内容,其中每一行代表外循环和内循环的整个迭代:
i0
现在数组长度为3:
i0 j1 j2
i1 j2
i2
数组长度为6:
i0 j1 j2 j3 j4 j5
i1 j2 j3 j4 j5
i2 j3 j4 j5
i3 j4 j5
i4 j5
i5
通过这种方式可以很容易地看出,我们在n
= 6时打印出6 + 5 + 4 + 3 + 2 + 1个语句。请注意,这只是所有语句的添加整数从1到6,或更一般地,从1到n
。从1到n
的整数之和的公知公式是(惊讶!)(n^2 + n)/2
。
我匆匆写了一下,但希望你看我是怎么来的。这与您的评估一致,即对于长度为10的输入,您有55次迭代:(10 ^ 2 + 10)/ 2 =(110)/ 2 = 55。
答案 1 :(得分:1)
是的,该程序的Big-O是O(N ^ 2)。
在Big-O表示法中,您只使用显性因子(例如忽略系数)。
所以,即使你更精确(实际答案是n(n-1)/ 2),符号也会忽略你的1/2系数&amp;任何小于n ^ 2的因子,这是主导因素。