算法的空间效率
似乎没有一本算法教科书提到那么多关于空间效率的问题,所以当我遇到要求仅需要恒定内存的算法的问题时,我不太明白。
使用常量内存的算法和不使用常量内存的算法的一些示例是什么?
It seems like none of the algorithm textbooks mentions about space efficiency as much, so I don't really understand when I encounter questions asking for an algorithm that requires only constant memory.
What would be an example of a few examples of algorithms that uses constant memory and algorithms that doesn't use constant memory?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果一个算法:
a) 递归多个取决于 N 的深度,或
b) 分配一定数量的内存,取决于 N,
那么它就不是常量内存。否则可能是:如果算法使用的内存量有一个恒定的上限,无论输入的大小/值是什么,形式上它就是常量内存。输入占用的内存不包括在内,因此有时为了清楚起见,您会谈论常量“额外”内存。
因此,这是一个常量内存算法,用于在 C 中查找整数数组的最大值:
这是一个非常量内存算法,因为它使用与输入数组中的元素数量成比例的堆栈空间。然而,如果编译器能够以某种方式将其优化为非递归等效项(C 编译器通常不会费心,除非有时使用尾部调用优化,而这在此处不起作用),则它可能会成为常量内存):
这是一个常量空间排序算法(这次是在 C++ 中),时间复杂度为 O(N!) 左右(也许是 O(N*N!)):
这是一个 O(N) 空间排序算法,它是 O(N^2) 时间:
If an algorithm:
a) recurses a number of levels deep which depends on N, or
b) allocates an amount of memory which depends on N
then it is not constant memory. Otherwise it probably is: formally it is constant-memory if there is a constant upper bound on the amount of memory which the algorithm uses, no matter what the size/value of the input. The memory occupied by the input is not included, so sometimes to be clear you talk about constant "extra" memory.
So, here's a constant-memory algorithm to find the maximum of an array of integers in C:
Here's a non-constant memory algorithm, because it uses stack space proportional to the number of elements in the input array. However, it could become constant-memory if the compiler is somehow capable of optimising it to a non-recursive equivalent (which C compilers don't usually bother with except sometimes with a tail-call optimisation, which wouldn't do the job here):
Here is a constant-space sort algorithm (in C++ this time), which is O(N!) time or thereabouts (maybe O(N*N!)):
Here is an O(N) space sort algorithm, which is O(N^2) time:
非常简单的例子:计算字符串中的字符数。它可以是迭代的:
或递归的:
第一个变体仅使用几个局部变量,无论字符串长度如何 - 它的空间复杂度为
O(1)
。第二个如果在没有递归消除的情况下执行,则需要一个单独的堆栈帧来存储与每个深度级别相对应的返回地址和局部变量 - 其空间复杂度为O(n)
其中n
是字符串长度。Very easy example: counting a number of characters in a string. It can be iterative:
or recursive:
The first variant only uses a couple of local variables regardless of the string length - it's space complexity is
O(1)
. The second if executed without recursion elimination requires a separate stack frame for storing the return address and local variables corresponding to each depth level - its space complexity isO(n)
wheren
is string length.以数组的排序算法为例。您可以使用与原始数组长度相同的新数组,将排序后的元素放入 (θ(n)) 中。或者您对数组就地进行排序,然后使用一个用于交换两个元素的附加临时变量 (θ(1))。
Take a sorting algorithms on an array for example. You can either use an new array of the same length as the original array where you put the sorted elements into (Θ(n)). Or you sort the array in-place and just use one additional temporary variable for swapping two elements (Θ(1)).