数组的空间复杂度?

Posted

技术标签:

【中文标题】数组的空间复杂度?【英文标题】:Space Complexity of an array? 【发布时间】:2017-11-09 21:19:35 【问题描述】:

我有一个大小为 N 的数组,N 为

这里的空间复杂度是多少。

O(1)(N) - 考虑约束 N。

【问题讨论】:

它只是 N 不是吗? 空间复杂度与算法无关吗?你的算法是什么?给定 N,创建一个大小为 N 的数组?是 O(N)。如果它在另一个输入大小为 n(与 N 无关)的算法中,而您只需要创建一个大小为 N 的数组,则为 O(1)。 @nafas 是的,我也这么认为。但是这里的 N 没有增长,它是常数。 @JeremyGrand 是的,这是有道理的。 @nafas 是的。我同意。我认为在这种情况下,如果数组大小是固定的并且它没有在任何地方增长,那么复杂度应该是 O(1)。 【参考方案1】:

我认为它将是 O(1)。如果空间大小随着 n 的增加而线性增加,则空间复杂度为 O(n)。但是在您的情况下,该函数在 200 之后不依赖于 n; f(n)=a*n+b..

【讨论】:

【参考方案2】:

只有当您尝试预测具有各种输入的算法的性能时,复杂性才相关。我认为在没有任何上下文的情况下仅谈论数组的空间复杂性没有任何意义。

如果你总是创建一个大小为 N(硬编码)的数组,它是 O(1),因为无论你的算法处理什么输入,你的数组占用的空间都是一样。

如果你的 N 随着输入的大小而增长,它是 O(f(n)),其中 f(n) 是 n(输入大小)和 N(大小数组)。

注意:公式 O(...) 是一个数学符号,用于表示大小,而不考虑乘数(抱歉,我的数学学位已经毕业,从未学过英文术语),所以,如果 N 是一个常数,O(N) = O(1)(它们的含义完全相同)。

如果我没记错的话,如果 f g ,O(f) = O(g)。因此,如果 N

【讨论】:

我个人认为这不是真的。常数值 K = 200,但 N 是可变的,它可以很小,也可以很大(N mate ,我认为它不对,比如在 java Max Integer = 2^31 -1 中,你还能认为 N 是的,我是从数学的角度讲的。问题是在计算 n(作为输入的大小)时必然是有界的。所以,我们实际上需要看看 K 对 n 是否有意义。 您对上下文是正确的:如果您创建一个函数createArray(N) return new Array(K) ,那么是的,您的代码的空间复杂度将为 O(1)。但是createArray(N) return new Array(N) 是 O(N) @olivarra1 我猜 OP 的问题是 N 随 n 增长(输入大小)但被 200 限制为强制阻止这部分算法占用过多资源的手段,这意味着当 n足够小,数组是O(n),但是当n很大时,它变成O(1)。我猜这是 O(1)【参考方案3】:

空间复杂度通常只针对算法定义。

但是让我们狡猾并根据您的问题形成算法。

Input: N values, N <= 200
Algorithm: Store all values
Output: None

空间复杂度是执行算法所需的内存量,与 N 的关系。

当您存储 1 个数字时,您将需要一个内存区域。当您存储 2 时,它会翻倍... 你的记忆复杂度是O(n),这意味着它是线性增长的;就像这个算法一样:

Input: N values, N <= 18,446,744,073,709,551,616 (unsigned int 64).
Algorithm: Store all values
Output: None

但是 200 是一个非常小的数字,我们不能说 O(1) 吗?

让我们再次变得狡猾,因为我们可以使这个 O(1):

Input: N values, N <= 200
Algorithm: Store all values in an array of size 200
Output: None

当您存储 1 个数字时,您将需要 200 个存储区域。当您存储 2 个数字时,您将需要 200 个存储区域。当您存储 200 个数字时,您将需要 200 个存储区域。这意味着内存是恒定的并且与 N 无关。因此复杂度是 O(1)。

需要注意的是,O(1) 并不意味着你需要的内存量是 1,它意味着你需要的内存量与 N 没有任何关系。因此它不会增长N 增长。

但是如果我的对象是 50GB 蓝光光盘怎么办? O(1) 应该非常小,但现在是 10 TB!

此时我们可能终于意识到我们并不总是需要使用大 O 符号。我们可以说我们需要存储 10 TB 的数据并购买一些硬盘。 如果你的老师对你是否为非常小的 N 或 O(n) 写 O(1) 大惊小怪,那么他是一个非常糟糕的老师。这个问题的答案既不会改变你的生活,也不会改变你的职业。 Big O Notation 仅适用于可以变得非常大的数字。

【讨论】:

【参考方案4】:

这取决于您的问题。如果您只使用恒定数量的内存(或空间)。因此,空间复杂度为 O(1)

但是,如果您有一些数据结构,例如一维数组,旨在容纳 N 个元素,其中 N 可能因输入而异,那么所需的内存量取决于 N。当 N 较小时,所需的空间也很小。当N很大时,所需的空间也很大。因此,所需空间和输入大小存在线性相关性。那是 O(N) 空间。

同样,如果你有一个大小为 NxN 的二维数组,那么通常所需的空间是 O(N^2)

考虑以下查找算法所需最小空间的示例:

 Scanner in = new Scanner(System.in);
 int n = in.nextInt();
 int[] array = new int[n];
 for(int i = 0; i < n; i++)
     array[i] = in.nextInt();
 
 int minimum = array[0];
 for(int i = 0; i < n; i++)
     if (array[i] < minimum)
        minimum = array[i];
     
 
 System.out.println(minimum);

在这里,我们有一个数组,其大小随n 而变化。总空间需求 = 2 + N,其中2 用于变量nminimumN 用于array。所以,这个算法的空间复杂度是O(N)

我希望这就是你要找的。​​p>

【讨论】:

【参考方案5】:

我有一个大小为 N 的数组,N 为

好的,你有一个大小为 N 的数组。怎么样?意思是,存储一些数据在空间复杂度方面没有任何意义,因为没有像使用该数组(空间)的某些代码(算法)这样的上下文。所以你不能测量什么都没有的空间复杂度(没有要运行的代码,只有数据)。

现在,如果您在某些上下文中使用此数组,例如创建 N 次输入数组的函数,其中 N

这里的空间复杂度是多少。

O(1) 或 (N) - 考虑约束 N?

在您的情况下,空间复杂度将为 O(1),因为没有要执行的代码,所以运行时间没有增长。只有一条数据(你的数组)。

希望对你有帮助

【讨论】:

以上是关于数组的空间复杂度?的主要内容,如果未能解决你的问题,请参考以下文章

数组循环移动 空间复杂度为O

查找数组中重复的唯一元素+时间复杂度O(n)+空间复杂度O

这个程序的空间复杂性是多少?

我们如何在 O(n) 时间和 O(1) 空间复杂度内找到数组中的重复数字

用最小的空间复杂度找出一个长度为n的数组且数据中的元素是[0,n-1]中任一个重复的数据。

每天一道leetCode