合并两(多)个排序的链表(算法17)
source link: https://allenwind.github.io/blog/3009/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
NLP、深度学习、机器学习、Python、Go
合并两(多)个排序的链表(算法17)
问题:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。
不难想出一个递归思路。先比较两链表首结点大小。较小的结点称为新合拼链表的首结点,同时,该结点所在的链表指针向前移动一位,我们称该链表尾子链表。这样,下一步就是子链表和较大结点所在的链表的比较和操作。和第一个类似,以此递归下去,直到两链表指针指向None。
根据递归版本我们不难使用队列辅助空间实现,但使用递归更简洁,下面给出递归的实现过程。
建立结点和链表
import random
from functools import total_ordering
@total_ordering
class Node:
def __init__(self, value):
self.value = value
self.next = None
def __repr__(self):
return 'Node<{}>'.format(self.value)
def __eq__(self, other):
return self.value == other.value
def __gt__(self, other):
return self.value > other.value
def build_linked_list(values):
if not values:
return None
root = Node(values[0])
p_node = root
for value in values[1:]:
p_node.next = Node(value)
p_node = p_node.next
return root
合并排序链表
def travel_list(linked):
while linked:
yield linked
linked = linked.next
def sorted_linked_list(p_head1, p_head2):
if p_head1 is None:
return p_head2
if p_head2 is None:
return p_head1
p_node = None # 没有必要在这里创建,仅用于表示
if p_head1 < p_head2:
p_node = p_head1
p_node.next = sorted_linked_list(p_head1.next, p_head2)
else:
p_node = p_head2
p_node.next = sorted_linked_list(p_head1, p_head2.next)
return p_node
不使用递归的方法如下
def sorted_linked_list(p_head1, p_head2):
if p_head1 is None:
return p_head2
if p_head2 is None:
return p_head1
p_node = None
while p_head1 and p_head2:
if p_head1 > p_head2:
head = p_head2
p_head2 = p_head2.next
else:
head = p_head1
p_head1 = p_head1.next
if p_node is None:
p_node = head
head = head.next
if p_head1:
head.next = p_head1
else:
head.next = p_head2
return p_node
简单的测试
def main():
p_head1 = build_linked_list(sorted(random.sample(range(20), 5)))
p_head2 = build_linked_list(sorted(random.sample(range(20), 5)))
for node in travel_list(p_head1):
print(node)
for node in travel_list(p_head2):
print(node)
p_head = sorted_linked_list(p_head1, p_head2)
for node in travel_list(p_head):
print(node)
if __name__ == '__main__':
main()
推广该问题,如果合并多个链表?
我们可以采取上述的思路,每个找出链表中最小的结点,作为头结点,然后该头结点所属的原先结点指针往后移动一个结点,以此下去。不使用递归的写法如下:
def find_min_node(lists):
if not lists:
return None
_min = None
index = 0
for i, node in enumerate(lists):
if _min is None:
_min = node
elif _min > node:
_min = node
index = i
if _min.next:
lists[index] = _min.next
else:
del lists[index]
return _min
def merge_lists(lists):
head = find_min_node(lists)
p_node = head
while lists:
p_node.next = find_min_node(lists)
p_node = p_node.next
return head
推广:链表的排序
Recommend
-
25
原题 在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。 示例 1: 输入: 4->2->1->3 输出: 1->2->3->4 示例 2: 输入: -1->5->3->4->...
-
6
LeetCode 图解 | 21.合并两个有序链表-五分钟学算法 当前位置:五分钟学算法 > LeetCodeAnimation > LeetCode 图解 | 21.合并两个有序链表
-
8
本文首发于公众号「五分钟学算法」,是图解 LeetCode 系列文章之一。 个人网站:https://www.cxyxiaowu.com
-
7
LeetCode 第 21 号问题:合并两个有序链表-程序员小吴 当前位置:程序员小吴 > LeetCodeAnimation > LeetCode 第 21 号问题:合并两个有序链表...
-
6
LeetCode 23Skip to content 仅记录,使用顺序合并,不包括分治和小顶堆(优先队列) 时间224ms,空间 2...
-
4
JZ-016-合并两个排序的链表发布于 12 月 5 日合并两个排序的链表输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链...
-
4
Mr.Feng BlogNLP、深度学习、机器学习、Python、Go二叉搜索树转换成排序双向链表遇到一道有趣的问题:把二叉搜索树转换成排序的双向链表。分享下思路,感受转换过...
-
3
-
2
链表排序问题总结归纳。 Merge Sorted ArrayDescription: Given two sorted integer arrays nums1 and nums2, merge nums2...
-
6
#yyds干货盘点# leetcode算法题:排序链表 精选 原创 灰太狼_cxh 2022-0...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK