我已经能够将两个排序的列表合并为一个,但是我不确定如何将它们合并到一个不递归的降序列表中。
答案 0 :(得分:2)
def merge(lst1, lst2):
if not lst1:
return [lst2[idx] for idx in range(len(lst2)-1, -1, -1)] # lst2[::-1]
if not lst2:
return [lst1[idx] for idx in range(len(lst1)-1, -1, -1)] # lst1[::-1]
merged_lst = []
i,j = len(lst1)-1 ,len(lst2)-1
while i > -1 and j > -1:
if lst1[i] > lst2[j]:
merged_lst.append(lst1[i])
i -=1
elif lst1[i] < lst2[j]:
merged_lst.append(lst2[j])
j -=1
else:
merged_lst.extend( [lst1[i],lst2[j]] )
i -=1
j -=1
if i > -1:
merged_lst.extend( lst1[idx] for idx in range(i,-1,-1))
# or merged_lst.extend( lst1[:i+1][::-1])
else:
merged_lst.extend( lst2[idx] for idx in range(j,-1,-1))
# or merged_lst.extend( lst2[:j+1][::-1])
return merged_lst
辅助功能
def reverse_lst( lst):
return [lst[idx] for idx in range(len(lst)-1, -1, -1)]
# if you don't even want to use list comprehension
def basic_reverse_lst( lst):
rev_lst = []
# start( inclusive), stop( exclusive), step
for idx in range(len(lst)-1 , -1, -1):
rev_lst.append( lst[idx])
return rev_lst
合并功能
def merge(lst1, lst2):
# assuming lst1 and lst2 are sorted list(ascending order)
空列表案例(我将在后面参考)
if not lst1:
# since lst1 is empty our merge list will only contain elements of lst2
return basic_reverse_lst(lst2) # if you don't want to use lst2[::-1] and list comprehension
if not lst2:
return reverse_lst(lst1)
merged_lst最终将由合并函数返回,它将包含我们的最终答案(降序)
merged_lst = []
i 和 j 分别用lst1和lst2的最后一个索引初始化,因为我们将反向遍历该列表,即从列表的最大元素到最小元素。
# last_idx = len(lst) -1
i,j = len(lst1)-1 ,len(lst2)-1
了解i
和j
的递减方式至关重要
想象两个箭头,一个指向lst1的索引i处的元素,另一个指向lst2的索引j处的元素,随着i和j的值变化,这些箭头将继续移动。
运行while循环,直到列表之一用尽为止,即直到我们没有完全遍历列表中的至少一个,这意味着一段时间后,至少一个箭头将指向索引0处的元素,并且end它将指向-1(在python中,它是列表的最后一个元素,但我们将其视为超出范围的索引,或者在这里只是表示我们已完全遍历此列表)。
while i > -1 and j > -1:
if lst1[i] > lst2[j]:
merged_lst.append(lst1[i])
i -=1
elif lst1[i] < lst2[j]:
merged_lst.append(lst2[j])
j -=1
else:
merged_lst.extend( [lst1[i],lst2[j]] )
i -=1
j -=1
'''
# you can use extend( some_sequence) or do append()
# here it depends what you want since you have not mentioned in your question exactly
# what kind of behaviour you want when elements of two list are same I presumed that you want to add both of them in merged list
merged_lst.append(lst1[i])
merged_lst.append(lst2[j])
'''
从列表中以相反的顺序提取其余元素,而我们尚未完全遍历,这与我们开始的情况相同,当传递给我们的func merge(lst1,lst2)的列表之一为空时,我们只需要要做的是反转非空列表(我们尚未完全遍历的列表)。
if i > -1:
# lst1 is not completely traversed yet
# merged_lst.extend( lst1[idx] for idx in range(i,-1,-1)) or # lst1[:i+1][::-1]
rest = lst1[:i+1] # rest contains elements of lst1 which we have not seen in while loop
merged_lst.extend( reverse_lst(rest))
else:
# lst2 is not completely traversed yet
# you can extract then reverse like we are doing in above if condition or you can simply do it in one line
merged_lst.extend( lst2[idx] for idx in range(j,-1,-1)) # or lst2[:j+1][::-1]
return merged_lst
print(merge([1,2,23,42],[])) # [42, 23, 2, 1]
print(merge([1,2,23,42], [5,7,11,19,21])) # [42, 23, 21, 19, 11, 7, 5, 2, 1]
print(merge([1,21,23,42], [5,7,11,19,21,97])) # [97, 42, 23, 21, 21, 19, 11, 7, 5, 1]
print(merge([1,19,19,21,21,23,42], [5,7,11,19,21,21,97])) # [97, 42, 23, 21, 21, 21, 21, 19, 19, 19, 11, 7, 5, 1]