Data structures 约束条件下数组中的最大k元素
给定一个整数数组,如何打印O(k)中最大的k个元素?Data structures 约束条件下数组中的最大k元素,data-structures,Data Structures,给定一个整数数组,如何打印O(k)中最大的k个元素? 重要提示:数组初始化为零。每当程序调用函数Add(i)时,第i个单元格将递增1。在调用print函数之前,如何利用这一事实来维护数组内部的秩序 所需空间复杂度:O(n),其中n是给定数组的大小。 我正在寻找一个不涉及堆的解决方案。这里有一个可能的解决方案,它可以通过使用大量的链接列表来工作 基本思想如下。对于每个数组位置,创建一个表示该数组元素的双链接列表单元格。然后,按数值对数组中的所有元素进行分组。例如,当您第一次创建数组时,所有的值都为
重要提示:数组初始化为零。每当程序调用函数
Add(i)
时,第i个单元格将递增1。在调用print函数之前,如何利用这一事实来维护数组内部的秩序
所需空间复杂度:O(n),其中n是给定数组的大小。我正在寻找一个不涉及堆的解决方案。这里有一个可能的解决方案,它可以通过使用大量的链接列表来工作 基本思想如下。对于每个数组位置,创建一个表示该数组元素的双链接列表单元格。然后,按数值对数组中的所有元素进行分组。例如,当您第一次创建数组时,所有的值都为零,您将有一个包含所有数组位置的双链接列表,如下所示:
+---+ +---+ +---+ +---+ +---+
| 0 | <-> | 1 | <-> | 2 | <-> | 3 | <-> | 4 |
+---+ +---+ +---+ +---+ +---+
+---+ +---+ +---+ +---+
Cells with value 0 | 0 | <-> | 1 | <-> | 2 | <-> | 4 |
+---+ +---+ +---+ +---+
+---+
Cells with value 1 | 3 |
+---+
+---+ +---+
Cells with value 0 | 1 | <-> | 4 |
+---+ +---+
+---+
Cells with value 1 | 0 |
+---+
+---+ +---+
Cells with value 2 | 2 | <-> | 3 |
+---+ +---+
+--------+---------+
| | |
v | |
+--------------------+ +---+ +---+
| Cells with value 0 | -> | 1 | <-> | 4 |
+--------------------+ +---+ +---+
^
| +-------------+
| | |
v v |
+--------------------+ +---+
| Cells with value 1 | -> | 0 |
+--------------------+ +---+
^
| +--------+---------+
| | | |
v v | |
+--------------------+ +---+ +---+
| Cells with value 2 | -> | 2 | <-> | 3 |
+--------------------+ +---+ +---+
^
|
+---- max
+--+++--+++--+++--++---+
| 0 | | 1 | | 2 | | 3 | | 4 |
+---+ +---+ +---+ +---+ +---+
每当您将某个值增加1时,请将其从其所在的列表中拼接出来,并将其添加到表示比上一个值大1的值的新列表中。例如,递增数组索引3会使情况如下所示:
+---+ +---+ +---+ +---+ +---+
| 0 | <-> | 1 | <-> | 2 | <-> | 3 | <-> | 4 |
+---+ +---+ +---+ +---+ +---+
+---+ +---+ +---+ +---+
Cells with value 0 | 0 | <-> | 1 | <-> | 2 | <-> | 4 |
+---+ +---+ +---+ +---+
+---+
Cells with value 1 | 3 |
+---+
+---+ +---+
Cells with value 0 | 1 | <-> | 4 |
+---+ +---+
+---+
Cells with value 1 | 0 |
+---+
+---+ +---+
Cells with value 2 | 2 | <-> | 3 |
+---+ +---+
+--------+---------+
| | |
v | |
+--------------------+ +---+ +---+
| Cells with value 0 | -> | 1 | <-> | 4 |
+--------------------+ +---+ +---+
^
| +-------------+
| | |
v v |
+--------------------+ +---+
| Cells with value 1 | -> | 0 |
+--------------------+ +---+
^
| +--------+---------+
| | | |
v v | |
+--------------------+ +---+ +---+
| Cells with value 2 | -> | 2 | <-> | 3 |
+--------------------+ +---+ +---+
^
|
+---- max
+--+++--++--++---+
值为0 | 0 | 1 | 2 | 4的单元格|
+---+ +---+ +---+ +---+
+---+
值为1 | 3的单元格|
+---+
然后递增单元格2将得出以下结果:
+---+ +---+ +---+
Cells with value 0 | 0 | <-> | 1 | <-> | 4 |
+---+ +---+ +---+
+---+ +---+
Cells with value 1 | 2 | <-> | 3 |
+---+ +---+
+---+ +---+ +---+
Cells with value 0 | 0 | <-> | 1 | <-> | 4 |
+---+ +---+ +---+
+---+
Cells with value 1 | 2 |
+---+
+---+
Cells with value 2 | 3 |
+---+
+--++--++---+
值为0 | 0 | 1 | 4的单元格|
+---+ +---+ +---+
+---+ +---+
值为1 | 2 | 3的单元格|
+---+ +---+
再次递增单元格3将得出以下结果:
+---+ +---+ +---+
Cells with value 0 | 0 | <-> | 1 | <-> | 4 |
+---+ +---+ +---+
+---+ +---+
Cells with value 1 | 2 | <-> | 3 |
+---+ +---+
+---+ +---+ +---+
Cells with value 0 | 0 | <-> | 1 | <-> | 4 |
+---+ +---+ +---+
+---+
Cells with value 1 | 2 |
+---+
+---+
Cells with value 2 | 3 |
+---+
+--++--++---+
值为0 | 0 | 1 | 4的单元格|
+---+ +---+ +---+
+---+
值为1 | 2的单元格|
+---+
+---+
值为2 | 3的单元格|
+---+
现在,假设您再次递增单元格(2)。这会将单元格(2)移动到值为2的单元格的链接列表中。由于不再需要值为(1)的单元格列表,我们可以删除它:
+---+ +---+ +---+
Cells with value 0 | 0 | <-> | 1 | <-> | 4 |
+---+ +---+ +---+
+---+ +---+
Cells with value 2 | 2 | <-> | 3 |
+---+ +---+
+--++--++---+
值为0 | 0 | 1 | 4的单元格|
+---+ +---+ +---+
+---+ +---+
值为2 | 2 | 3的单元格|
+---+ +---+
为了增加0,我们将重新创建值1的列表,如下所示:
+---+ +---+
Cells with value 0 | 1 | <-> | 4 |
+---+ +---+
+---+
Cells with value 1 | 0 |
+---+
+---+ +---+
Cells with value 2 | 2 | <-> | 3 |
+---+ +---+
+--++---+
值为0 | 1 | 4的单元格|
+---+ +---+
+---+
值为1 | 0的单元格|
+---+
+---+ +---+
值为2 | 2 | 3的单元格|
+---+ +---+
要在时间O(k)中打印出前k个元素,请从最高值的链表开始,并在那里打印出元素。如果这还不够,那么转到第二高值列表并打印其内容,然后是下一个列表,然后是下一个列表,以此类推
挑战在于如何维护这些单独的链接列表。我们需要能够做到以下几点:
- 维护列表的双链接列表。“列表列表”中的每个单元格将存储与该列表中的单元格关联的编号
- 保持指向“列表列表”中最后一个单元格的指针,这样我们就可以高效地打印前k个元素
- 用指向“列表列表”单元格的指针注释每个现有单元格,这样,当我们进行增量时,我们可以确定它属于哪个列表
+---+ +---+ +---+ +---+ +---+
| 0 | <-> | 1 | <-> | 2 | <-> | 3 | <-> | 4 |
+---+ +---+ +---+ +---+ +---+
+---+ +---+ +---+ +---+
Cells with value 0 | 0 | <-> | 1 | <-> | 2 | <-> | 4 |
+---+ +---+ +---+ +---+
+---+
Cells with value 1 | 3 |
+---+
+---+ +---+
Cells with value 0 | 1 | <-> | 4 |
+---+ +---+
+---+
Cells with value 1 | 0 |
+---+
+---+ +---+
Cells with value 2 | 2 | <-> | 3 |
+---+ +---+
+--------+---------+
| | |
v | |
+--------------------+ +---+ +---+
| Cells with value 0 | -> | 1 | <-> | 4 |
+--------------------+ +---+ +---+
^
| +-------------+
| | |
v v |
+--------------------+ +---+
| Cells with value 1 | -> | 0 |
+--------------------+ +---+
^
| +--------+---------+
| | | |
v v | |
+--------------------+ +---+ +---+
| Cells with value 2 | -> | 2 | <-> | 3 |
+--------------------+ +---+ +---+
^
|
+---- max
+--++---+
值为0 | 1 | 4的单元格|
+---+ +---+
+---+
值为1 | 0的单元格|
+---+
+---+ +---+
值为2 | 2 | 3的单元格|
+---+ +---+
实际上是这样的:
+---+ +---+ +---+ +---+ +---+
| 0 | <-> | 1 | <-> | 2 | <-> | 3 | <-> | 4 |
+---+ +---+ +---+ +---+ +---+
+---+ +---+ +---+ +---+
Cells with value 0 | 0 | <-> | 1 | <-> | 2 | <-> | 4 |
+---+ +---+ +---+ +---+
+---+
Cells with value 1 | 3 |
+---+
+---+ +---+
Cells with value 0 | 1 | <-> | 4 |
+---+ +---+
+---+
Cells with value 1 | 0 |
+---+
+---+ +---+
Cells with value 2 | 2 | <-> | 3 |
+---+ +---+
+--------+---------+
| | |
v | |
+--------------------+ +---+ +---+
| Cells with value 0 | -> | 1 | <-> | 4 |
+--------------------+ +---+ +---+
^
| +-------------+
| | |
v v |
+--------------------+ +---+
| Cells with value 1 | -> | 0 |
+--------------------+ +---+
^
| +--------+---------+
| | | |
v v | |
+--------------------+ +---+ +---+
| Cells with value 2 | -> | 2 | <-> | 3 |
+--------------------+ +---+ +---+
^
|
+---- max
+--------+---------+
| | |
v||
+--------------------+ +---+ +---+
|值为0 |->1 | 4的单元格|
+--------------------+ +---+ +---+
^
| +-------------+
| | |
v v|
+--------------------+ +---+
|值为1 |->0的单元格|
+--------------------+ +---+
^
| +--------+---------+
| | | |
v||
+--------------------+ +---+ +---+
|值为2 |->2 | 3的单元格|
+--------------------+ +---+ +---+
^
|
+----马克斯
这允许我们将元素从列表中拼接出来,找出它们属于哪个列表,然后确定是将它们拼接到我们上面的列表中,还是在两个列表之间创建一个新列表
数组中的每个元素都单独使用空间O(1)。每个“列表列表”单元格占用空间O(1)a