Python 如何合并两个列表并在';线性';时间
我有这个,它是有效的:Python 如何合并两个列表并在';线性';时间,python,list,merge,Python,List,Merge,我有这个,它是有效的: # E. Given two lists sorted in increasing order, create and return a merged # list of all the elements in sorted order. You may modify the passed in lists. # Ideally, the solution should work in "linear" time, making a single # pass of bo
# E. Given two lists sorted in increasing order, create and return a merged
# list of all the elements in sorted order. You may modify the passed in lists.
# Ideally, the solution should work in "linear" time, making a single
# pass of both lists.
def linear_merge(list1, list2):
finalList = []
for item in list1:
finalList.append(item)
for item in list2:
finalList.append(item)
finalList.sort()
return finalList
# +++your code here+++
return
但是,我真的很想把这些东西学好。:)“线性”时间是什么意思?意味着程序的运行时间与输入的长度成正比。在这种情况下,输入由两个列表组成。如果列表的长度是原来的两倍,那么程序运行的时间大约是原来的两倍。从技术上讲,我们认为算法应该是,其中n是输入的大小(在本例中是两个输入列表的长度之和)
这似乎是家庭作业,所以我不会给你答案。尽管这不是家庭作业,但我认为最好的方法是拿一支笔和一张纸,构建两个分类的小示例列表,然后手动找出如何合并这两个列表。一旦你弄明白了这一点,实现算法就是小菜一碟
(如果一切顺利,你会注意到你只需要在一个方向上对每个列表迭代一次。这意味着算法确实是线性的。祝你好运!)意味着时间是一个函数,其中n-输入的项目数(列表中的项目)。f(n)=O(n)表示存在常数x和y,使得x*n线性时间表示O(n)复杂度。您可以在此处阅读有关算法复杂性和大O符号的内容:。 您应该尝试合并这些列表,而不是在最终列表中获得它们之后,尝试逐渐合并它们-添加一个元素,确保结果已排序,然后添加下一个元素。。。这应该会给你一些想法。线性意味着O(n)in,而你的代码使用了
sort()
,这很可能是O(nlogn)
这个问题是在问这个问题。一个简单的Python实现是:
def merge(l, m):
result = []
i = j = 0
total = len(l) + len(m)
while len(result) != total:
if len(l) == i:
result += m[j:]
break
elif len(m) == j:
result += l[i:]
break
elif l[i] < m[j]:
result.append(l[i])
i += 1
else:
result.append(m[j])
j += 1
return result
>>> merge([1,2,6,7], [1,3,5,9])
[1, 1, 2, 3, 5, 6, 7, 9]
def合并(l,m):
结果=[]
i=j=0
总计=长(l)+长(m)
而len(结果)!=总数:
如果len(l)=i:
结果+=m[j:]
打破
elif len(m)=j:
结果+=l[i:]
打破
以利夫l[i]>>合并([1,2,6,7],[1,3,5,9])
[1, 1, 2, 3, 5, 6, 7, 9]
线性时间意味着所花费的时间由一些未定义的常数乘以(在本上下文中)两个列表中要合并的项目数限定。您的方法无法实现这一点-它需要O(n logn)时间
当根据问题的大小指定一个算法需要多长时间时,我们忽略了一些细节,比如机器有多快,这基本上意味着我们忽略了所有的常量项。我们用“渐近符号”来表示。这些基本上描述了曲线的形状,你将在一个图表中绘制问题大小(x)和时间(y)。逻辑是,如果问题足够大,糟糕的曲线(快速变陡的曲线)总是会导致执行时间变慢。对于非常小的问题(取决于常数,这可能取决于机器),执行速度可能更快,但对于小问题,执行时间通常不是大问题
“大O”指定执行时间的上限。平均执行时间和下限有相关的符号,但“big O”是最受关注的符号
- O(1)是常数时间-问题的大小无关紧要
- O(logn)是一条很浅的曲线——随着问题的扩大,时间会增加一点
- O(n)是线性时间-每增加一个单位意味着它需要一个大致恒定的额外时间。这张图(大致)是一条直线
- 当问题变得更复杂时,O(n logn)曲线上升得更陡,但幅度不是很大。这是通用排序算法所能做的最好的事情
- 当问题变得更复杂时,O(n平方)曲线向上的幅度更大。这对于较慢的排序算法(如冒泡排序)是典型的
一些细节。。。首先,将项目放回到列表中只是为了再次将其拉出显然是愚蠢的,但这使解释更容易。下一步-一个输入列表将在另一个之前耗尽,因此您需要处理这个问题(基本上只需清空其他列表的其余部分并将其添加到输出中)。最后,您实际上不必从输入列表中删除项目,同样,这只是解释。您可以单步执行。此线程包含线性时间合并算法的各种实现。请注意,出于实际目的,您将使用
heapq.merge
如果您以反向排序的顺序构建结果,您可以使用pop()
并且仍然是O(N)列表右端的
pop()
不需要移动元素,O(1)也不需要移动元素在返回列表之前将其反转为O(N)
更简单的版本需要大小相同的列表:
def merge_sort(L1, L2):
res = []
for i in range(len(L1)):
if(L1[i]<L2[i]):
first = L1[i]
secound = L2[i]
else:
first = L2[i]
secound = L1[i]
res.extend([first,secound])
return res
def merge_排序(L1、L2)
>>> def merge(l, r):
... result = []
... while l and r:
... if l[-1] > r[-1]:
... result.append(l.pop())
... else:
... result.append(r.pop())
... result+=(l+r)[::-1]
... result.reverse()
... return result
...
>>> merge([1,2,6,7], [1,3,5,9])
[1, 1, 2, 3, 5, 6, 7, 9]
def merge_sort(L1, L2):
res = []
for i in range(len(L1)):
if(L1[i]<L2[i]):
first = L1[i]
secound = L2[i]
else:
first = L2[i]
secound = L1[i]
res.extend([first,secound])
return res