人生苦短,我用Python

21.合并两个有序链表

题目描述:

将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

示例:

输入:1->2->4, 1->3->4

输出:1->1->2->3->4->4

解题思路:

刚看到这一题,我的第一想法是把链表的值都拿出来,放到一个列表里,排序后,再放入一个新的链表,就产生一个有序的新链表。想法很美好,但是现实很残酷,领扣执行返回超出时间限制。这就说明算法不合理,需要优化。因为本人对链表接触很少,所以没有什么好的想法,所以就到网上搜索解决方案,虽然没有现成的Python写的合并两个链表的算法,但有其他原语言的,通过借鉴其思想,写了下面的算法,通过了测试。

代码实现:

# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def mergeTwoLists(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
#创建一个新的头结点,代表一个新的链表的头结点
tmp=ListNode(0)
#创建一个引用,保持当前指向位置
save=tmp
#比较大小,并串联起来,当两个链表都不为空时
while l1!=None and l2!=None:
if l1.val
tmp.next=l1
l1=l1.next
tmp=tmp.next
else:
tmp.next=l2
l2=l2.next
tmp=tmp.next
if l1==None:
tmp.next=l2
if l2==None:
tmp.next=l1
return save.next

算法解析:

算法总体思想就是,先定义一个新的链表的头节点,然后创建一个引用,保存当前指向位置,因为最后你要从这个指向位置开始往后取出一个链表。

当两个有序列表都不为空时,如果l1.val的值小于l2.val的值,则头节点的下一个节点指向l1,也就是上面代码中的tmp.next=l1,然后l1重新赋值,指向l1的下一个节点,即l1=l1.next,现在新链表也就变成了,tmp.val=0(头节点的值),tmp.next=l1(头节点的下一个指向节点是l1),这时需给tmp变量重新赋值,指向tmp.next。

当l1.val大于等于l2.val时,也就是上述代码的else逻辑,整体思想和上面逻辑差不多,只是tmp.next指向l2,总结下来就是谁的值小,新链表的下一节点指针就指向谁,柿子总是挑软的捏嘛,然后指针移动。

算法结果:

从图表中看出,执行效果还是可以的,战胜了95.89%的Python3提交记录。

看了一下在这个算法的前面的代码编写,思路基本是一样的,主要是代码简化一点,下面放出别人家的代码~_~

# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def mergeTwoLists(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode

思路:

注意返回的也是一个有序列表

比较当前l1 与 l2 大小 最后拼接剩余部分

"""
head = temp = ListNode(0)
while l1 and l2:
if l1.val <= l2.val:
temp.next = l1
l1 = l1.next
else:
temp.next = l2
l2 = l2.next
temp = temp.next
temp.next = l1 or l2
return head.next