Performance 大O,一系列n个数求和的复杂性是什么?

Performance 大O,一系列n个数求和的复杂性是什么?,performance,algorithm,optimization,complexity-theory,big-o,Performance,Algorithm,Optimization,Complexity Theory,Big O,我一直认为: 1+2+3+…+n是O(n),两个n乘以n的矩阵求和将是O(n^2) 但今天我从教科书上读到,“根据前n个整数之和的公式,这是n(n+1)/2”,然后是:(1/2)n^2+(1/2)n,然后是O(n^2) 我错过了什么 您有一个公式,它不依赖于要添加的数字的数量,因此它是一个常数时间算法,或O(1) 如果你一次加一个数字,那么它就是O(n)。公式是一条捷径;这是一种不同的、更有效的算法。当所添加的数字都为1..n时,快捷方式有效。如果你有一个非连续的数字序列,那么快捷公式就不起作用

我一直认为:

1+2+3+…+n
是O(n),两个n乘以n的矩阵求和将是O(n^2)

但今天我从教科书上读到,“根据前n个整数之和的公式,这是n(n+1)/2”,然后是:(1/2)n^2+(1/2)n,然后是O(n^2)


我错过了什么

您有一个公式,它不依赖于要添加的数字的数量,因此它是一个常数时间算法,或O(1)

如果你一次加一个数字,那么它就是O(n)。公式是一条捷径;这是一种不同的、更有效的算法。当所添加的数字都为1..n时,快捷方式有效。如果你有一个非连续的数字序列,那么快捷公式就不起作用了,你必须回到逐个算法

但这些都不适用于数字矩阵。要添加两个矩阵,仍然是O(n^2),因为您要添加n^2个不同的数字对,以获得一个包含n^2个结果的矩阵。

n(n+1)/2是对n个整数的连续序列求和的快速方法(从1开始)。我想你把算法和大的oh符号搞混了

如果你认为它是一个函数,那么这个函数的最大复杂性是O(1):

第一个整数的公共整数和(整数n){ 返回(n*(n+1))/2; } 天真的实现将具有O(n)的巨大oh复杂性

第一个整数的公共整数和(整数n){
整数和=0;

对于(int i=1;i而言,对N个任意整数求和与N个整数求和是有区别的。对于1+2+3+4+…+N,您可以利用这样一个事实,即它们可以用一个公共和分成对,例如1+N=2+(N-1)=3+(N-2)=…=N+1。这是N+1,N/2倍。(如果有一个奇数,其中一个将是不成对的,但只要稍加努力,你就会发现在这种情况下同样的公式成立。)


但这不是O(N^2)。它只是一个使用N^2的公式,实际上是O(1)。O(N^2)的意思是(大致上)计算它的步骤数增长像N^2,对于大的N。在这种情况下,不管N是多少,步骤数都是相同的。

一个问题实际上并不复杂,而是一个算法的复杂度

在您的例子中,如果您选择遍历所有数字,那么复杂性实际上是,
O(n)


但这不是最有效的算法。更有效的算法是应用公式-
n*(n+1)/2
,它是常数,因此复杂性是
O(1)

您混淆了运行时的复杂性和结果的大小(复杂性)

求和的运行时间,一个接一个,前n个连续的数字实际上是O(n)

但是结果的复杂性,即“从1到n的和”=n(n–1)/2的大小是O(n^2)


< p>1,但对于任意大数,这是简单的,因为增加大数比增加小数字要长。对于精确的运行时分析,你确实必须考虑结果的大小。然而,这在编程中通常是不相关的,甚至在纯理论计算机科学中也不相关。在两个域中,求和数都是。通常被认为是一个O(1)操作,除非域另有明确要求(即,在为bignum库实现操作时)。

可用于确定任何函数的增长率


在这种情况下,这本书似乎不是在讨论计算值的时间复杂性,而是在讨论值本身

可以使用两种方法找到n个自然数系列之和的答案。第一种方法是将循环中的所有数字相加。在这种情况下,算法是线性的,代码如下所示

 int sum = 0;
     for (int i = 1; i <= n; i++) {
     sum += n;
   }
 return sum;
int和=0;

对于(int i=1;i,我猜这实际上是对的引用,它在
StringBuffer
实现中有这一段:

在每次连接时,将创建字符串的新副本,并且 一个字符一个字符地复制两个字符串 迭代要求我们复制
x
字符。第二次迭代 需要复制
2x
字符。第三次迭代需要
3x
,并且 依此类推。因此,总时间是
O(x+2x+…+nx)
。这减少了 到
O(xn²)
(为什么不是
O(xnⁿ)?因为
1+2+…n
等于
n(n+1)/2
或者,
O(n²)


无论出于什么原因,我在第一次通读时也发现这有点令人困惑。重要的一点是,
n
正在乘以
n
,或者换句话说,
正在发生,并且占主导地位。这就是为什么
O(xn²)
最终只是
O(n²)
--
x
有点像是在转移注意力。

添加前n个数字:

以算法为例:

Series_Add(n)

   return n*(n+1)/2
Series_Add_pseudo(n):
   sum=0   
   for i= 1 to n:
      sum += i
   return sum
该算法确实在O(|n | ^2)中运行,其中| n |是n的长度(位),而不是大小,这仅仅是因为两个数字的乘法,k位中的一个和l位中的另一个在O(k*l)时间内运行

小心

考虑到该算法:

Series_Add(n)

   return n*(n+1)/2
Series_Add_pseudo(n):
   sum=0   
   for i= 1 to n:
      sum += i
   return sum
这是一种天真的方法,你可以假设这个算法在线性时间内运行,或者通常在多项式时间内运行。事实并非如此

n的输入表示(长度)为O(logn)位(除一元编码外的任何n元编码),算法(尽管在幅度上呈线性运行)在输入长度上呈指数运行。 这实际上是伪多项式算法的情况。它似乎是多项式,但不是

您甚至可以在python(或任何编程语言)中尝试它,使用中等长度的数字,如200位

应用第一种算法,结果会在瞬间出现,然后应用第二种算法,