Algorithm 合并两个非常大的列表

Algorithm 合并两个非常大的列表,algorithm,list,merge,Algorithm,List,Merge,给定一个大小为2n-1的元素列表,该列表如下所示: x1,x2,x3,…,xn,y1,y2,y3,….y(n-1) 将其转换为: x1, y1, x2, y2, x3, y3, ........., y(n-1), xn 我可以为每个列表使用两个迭代器,并得到O(n)时间复杂度和O(n)空间复杂度的解决方案。但是,如果我的n非常大,有没有一种方法可以在较低的空间复杂度下实现这一点?感觉这可以用O(1)空间和O(n)时间来实现,但该算法绝不简单。基本上取一个不合适的元素,比如说x2,看看它在最终

给定一个大小为2n-1的元素列表,该列表如下所示:

x1,x2,x3,…,xn,y1,y2,y3,….y(n-
1)

将其转换为:

x1, y1, x2, y2, x3, y3, ........., y(n-1), xn

我可以为每个列表使用两个迭代器,并得到O(n)时间复杂度和O(n)空间复杂度的解决方案。但是,如果我的n非常大,有没有一种方法可以在较低的空间复杂度下实现这一点?

感觉这可以用O(1)空间和O(n)时间来实现,但该算法绝不简单。基本上取一个不合适的元素,比如说x2,看看它在最终排列中需要在哪里,取出存在的元素(即x3)并放入x2。 现在看看x3需要去哪里,等等

当循环结束时,取下一个不合适的元件(如果有)

让我们做一个例子:

x1 x2 x3 y1 y2      x2 is out of place so take it into temp storage
x1 -- x3 y1 y2      temp: x2       needs to go where x3 currently is
x1 -- x2 y1 y2      temp: x3       needs to go where y2 currently is
x1 -- x2 y1 x3      temp: y2       needs to go where y1 currently is
x1 -- x2 y2 x3      temp: y1       needs to go into the empty slot
x1 y1 x2 y2 x3      all elements in place -> finished
如果数组索引从0开始,则元素在k处的最终位置由

2k            if k < n
2(k-n) + 1    if k >= n
我目前没有一个简单的解决办法

如果每个数组元素有一个可用的存储位,那么它就很简单了,但是我们回到了O(n)存储

lst = 'x1 x2 x3 x4 x5 y1 y2 y3 y4 y5'.split()

lst
Out[9]: ['x1', 'x2', 'x3', 'x4', 'x5', 'y1', 'y2', 'y3', 'y4', 'y5']

out = sum((list(xy) for xy in zip(lst[:len(lst)//2], lst[len(lst)//2:])), [])

out
Out[11]: ['x1', 'y1', 'x2', 'y2', 'x3', 'y3', 'x4', 'y4', 'x5', 'y5']

我无法准确地描述这一点。你能解释一下使用3-4个元素吗?看起来很整洁。但是我如何确保我没有失去任何元素呢?另外,找到我的元素的位置有多复杂?我有什么想法吗?在完成一个周期后,你如何知道“下一个不合适的元素”呢?如果你选择了一个元素,你如何知道“它需要在最终排列中的位置”?你真的必须明确地合并这两个列表吗?在没有真正执行合并的情况下,您可以很容易地从结果列表中说出第k个元素是什么。有关有效地应用任意置换的更一般的问题,请参见:,@augurar Yes,但相同的方法-将2xN矩阵转置这需要
O(n)
额外的空间,这是OP明确想要避免的。
lst = 'x1 x2 x3 x4 x5 y1 y2 y3 y4 y5'.split()

lst
Out[9]: ['x1', 'x2', 'x3', 'x4', 'x5', 'y1', 'y2', 'y3', 'y4', 'y5']

out = sum((list(xy) for xy in zip(lst[:len(lst)//2], lst[len(lst)//2:])), [])

out
Out[11]: ['x1', 'y1', 'x2', 'y2', 'x3', 'y3', 'x4', 'y4', 'x5', 'y5']