没有一般的排序算法可以在 O(n) 时间内做到这一点。此外,如果没有额外的限制(例如,十亿个数字取自数字 1 到 1,000,000),根本就没有排序算法可以解决这个问题。
但是,有一个简单的 O(n) 算法可以做到这一点:
- 用 1,000,000 个空单元格初始化返回缓冲区
- 对于 1,000,000,000 列表中的每个项目,请执行以下操作:
- 依次检查 1,000,000 个单元格中的每一个
- 如果输入的数字大于缓冲区中的数字,则交换它们并继续
- 如果您正在查看空白单元格,请输入您按住的数字
- 如果您到达列表末尾并持有一个数字,请将其扔掉
这是一个包含 10 项内容的示例,我们想要最大的 5 项:
Input: [6, 2, 4, 4, 8, 2, 4, 1, 9, 2]
Buffer: [-, -, -, -, -]
[6, -, -, -, -] … see a blank, drop the 6
[6, 2, -, -, -] … 2 < 6, skip, then see a blank, drop the 2
[6, 4, 2, -, -] … 4 < 6 but 4 > 2, swap out 2, see blank, drop 2
[6, 4, 4, 2, -] … 4 <= 4,6 but 4 > 2, swap out 2, see blank, drop 2
[8, 6, 4, 4, 2] … 8 > 6, swap, then swap 6 for 4, etc.
[8, 6, 4, 4, 2] … 2 <= everything, drop it on the floor
[8, 6, 4, 4, 4] … 4 <= everything but 2, swap, then drop 2 on floor
[8, 6, 4, 4, 4] … 1 <= everything, drop it on the floor
[9, 8, 6, 4, 4] … 9 > everything, swap with 8 then drop a 4 on the floor
[9, 8, 6, 4, 4] … 2 <= everything, drop it on the floor
您对输入中的每个元素进行 1,000,000 次比较,并可能进行多达 1,000,000 次交换(考虑按升序排序的输入)。这意味着您所做的工作与 1,000,000 * n 成正比,这是输入 n 大小的线性工作量。