Algorithm 合并两个非常大的列表
给定一个大小为2n-1的元素列表,该列表如下所示: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,看看它在最终
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']