这不是一个完整的答案。但如果列表已排序,则您的问题可以很容易地在O(n)
时间内完成。为此,请将所有数字排列成链接列表。维护一个指向头部和中间某个位置的指针。在每一步中,从头部取出前两个元素,打印它们,将中间指针推进到应该放置总和的位置,并插入总和。
起始指针将移动接近2n
次,中间指针将移动约n
次,进行n
次插入。所有这些操作都是O(1)
,因此总和为O(n)
。
通常情况下,您无法以时间O(n)
排序,但有许多特殊情况可以做到。因此,在某些情况下是可行的。
当然,一般情况下不能在时间O(n)
内解决。为什么呢?因为根据您的输出,您可以在时间O(n)
内运行程序的输出,按顺序构建成对求和的列表,并将它们过滤出输出。剩下的就是原始列表中的元素按顺序排列。这将得到一个O(n)
的常规排序算法。
更新: 我被要求展示如何从输出(10, 11), (12, 13), (14, 15), (21, 25), (29, 46)到输入列表?诀窍是始终保持一切有序,然后您就知道如何查找。对于正整数,下一个即将使用的总和始终位于该列表的开头。
Step 0: Start
input_list: (empty)
upcoming sums: (empty)
Step 1: Grab output (10, 11)
input_list: 10, 11
upcoming_sums: 21
Step 2: Grab output (12, 13)
input_list: 10, 11, 12, 13
upcoming_sums: 21, 25
Step 3: Grab output (14, 15)
input_list: 10, 11, 12, 13, 14, 15
upcoming_sums: 21, 25, 29
Step 4: Grab output (21, 25)
input_list: 10, 11, 12, 13, 14, 15
upcoming_sum: 29, 46
Step 5: Grab output (29, 46)
input_list: 10, 11, 12, 13, 14, 15
upcoming_sum: 75
z
插入列表时,你在其上贴一个标记,表示“这是一个计算出来的值,而不是原始值”。最后,假设当你呈现数字时,只打印出未设置标记的数字。然后,您已经在O(n)
时间内对数字列表进行了排序。因此,需要某种欺骗手段,例如对固定大小整数执行基数排序。 - Steve Jessop