在熟悉的问题中,数组中的每个元素最多有k个位置距离其正确位置,无论是向左还是向右,最小堆实现如下。
创建一个大小为k 1的min-heap。因此,min堆的根是已排序数组的最小元素。对于剩余的n-(k 1)元素,在每次迭代中,选择是在[i]和已在堆中的元素之间。因此,在堆中插入[i],堆化并提取min。这将继续填充已排序数组的a[i-k]元素。
时间复杂度:O(k)O(n-k)。对数(k)
空间复杂度:O(k)
我的问题是:这可以用O(1)空间复杂度来实现吗?
我在这里找到了一种方法,但感觉不到。有人能详细说明一下吗?
你可以在适当的地方这样做。从远端开始,使用最大堆而不是最小堆。将最后一块2k个元素放置到位。将第一个提取的元素存储在变量中;后续元素位于2k的最后一个块(包含堆结构)之前的空白位置,类似于常规堆。当只剩下1个方块时,将其堆入到位。最后一个O(n)过程需要“旋转”最终块回到初始块。旋转不是微不足道的,但可以在O(n)和O(1)空间中完成。
基本思想是将堆存储在数组中,使用它对数组的其余元素进行排序,然后对堆部分本身进行排序。
这是一个使用min-heap的变体,可能更容易理解。
>
对数组的第一个k 1
元素进行堆化。堆的最小元素将是整个数组的最小值。
k+1 | n-(k+1)
heap | unsorted
将堆的最小元素与未排序部分的第一个元素交换并重新堆化。
k+1 | 1 | n-(k+2)
heap | sorted | unsorted
重复步骤2,直到不再有未处理的元素。此时,堆包含数组中最大的元素,其余元素按排序顺序排列。
k+1 | n-(k+1)
heap | sorted
对数组的堆部分排序
k+1 | n-(k+1)
sorted heap | sorted
将排序后的堆移动到数组的另一端。数组现在已排序。
n-(k+1)| k+1
sorted | sorted heap
我已经在Java和C中找到了这个问题的几个实现,但我还没有找到一个使用JavaScript的示例。这是一个相当常见的技术面试问题: 在2n空间中对堆栈进行排序。(仅使用2个堆栈对堆栈进行排序)
我不明白堆排序的空间复杂度是怎样的O(1)?虽然快速排序不使用任何额外的数组(即就地),但在最坏情况下其空间复杂度为O(n),在最佳情况下为O(lg n),因为在递归调用的后端使用堆栈。我说得对吗? 堆排序也是如此。虽然,它是就地的,但是由于Build-Heap函数调用Max-Heapify函数,所以它的空间复杂度应该等于Max-Heapify,即O(lg n)。不是吗?此外,稍后在根节点调用Ma
输入=堆栈数 但是你只能弹出输入,你不能推到它。输出也是另一个堆栈,你可以返回并推到它,但不能弹出 所以如果 由于您无法在中返回到
我试图找出以下问题的最佳解决方案:给定一个范围为1-5的20个整数的堆栈,对堆栈进行排序,使只有1-4的值保持升序。您一次只能移动一个值。 我实现了一个迭代的 我应该考虑哪一种类型?我应该考虑哪些数据类型?对于给定的问题,最好的可能更坏的情况是什么O(?)?
我正在阅读《破解编码面试》一书,遇到了一个问题:“编写一个程序,按升序对堆栈进行排序。您可以使用其他堆栈来保存项目,但不能将元素复制到任何其他数据结构(如数组)中。堆栈支持以下操作:push、pop、peek、isEmpty。” 这本书用O(n^2的时间复杂度和空间复杂度给出了答案。 但是,我偶然发现了这个博客,它使用快速排序方法在O(n log n)时间复杂性中提供了答案。 我想知道的是空间复杂
我注意到一件非常奇怪的事情。 读完这节课后,我在C中实现了一些堆排序代码。 代码如下。 奇怪的是,对我来说,构建min堆-提取min(或在构建min堆后在根目录下执行min-heapify)应该按升序进行。然而,在执行此代码并打印出结果向量后,我得到: 在试图弄清楚发生了什么的时候,我改变了 到 最终选择较大(或最大)的父节点和子节点,得到的向量为: 我是否做错了什么,或者我对堆/堆排序的理解不清