问题描述
该题目可用两类方法来完成,一类递归,一类迭代。
方法一:迭代
迭代方法我用了两种方式来实现,一个是边判断结点值的大小边创建新链表,一个是完全判断完成再创建新链表(主要是想复习一下昨天学到的队列的用法)
1、边判断边创建
class Solution(object):
def mergeTwoLists(self, list1, list2):
"""
:type list1: Optional[ListNode]
:type list2: Optional[ListNode]
:rtype: Optional[ListNode]
"""
'''方法一:边判断边创建'''
if not list1 and not list2:
return list1
if not list1 and list2:
return list2
if list1 and not list2:
return list1
dummy = ListNode(-1)
p = dummy
while list1 and list2:
if list1.val < list2.val:
node = ListNode(list1.val)
p.next = node
p = p.next
list1 = list1.next
else:
node = ListNode(list2.val)
p.next = node
p = p.next
list2 = list2.next
while list1:
node = ListNode(list1.val)
p.next = node
p = p.next
list1 = list1.next
while list2:
node = ListNode(list2.val)
p.next = node
p = p.next
list2 = list2.next
return dummy.next
我这里多了一个不走,就是每次都根据list1和list2的结点值来新创建一个结点,然后再链接。其实没有这个必要,我这么做的原因是因为之前我在做类似的题目的时候有出现过环的现象。不够我后面想了一下,本题是不会存在成环的可能性,因此可以在判断完大小之后直接链接,不过要注意一定要及时的将指针后移一位。完整代码如下:
# Definition for singly-linked list.
class ListNode(object):
def __init__(self, val=0, next=None):
self.val = val
self.next = next
# Definition for linklist.
class LinkList(object):
def __init__(self):
self.head = None
def linklist(self, data):
if not data:
return None
head = ListNode(data[0])
p = head
for i in data[1:]:
node = ListNode(i)
p.next = node
p = p.next
return head
# merge
class Solution(object):
def mergeTwoLists(self, list1, list2):
"""
:type list1: Optional[ListNode]
:type list2: Optional[ListNode]
:rtype: Optional[ListNode]
"""
'''方法一:边判断边创建'''
if not list1 and not list2:
return list1
if not list1 and list2:
return list2
if list1 and not list2:
return list1
dummy = ListNode(-1)
p = dummy
while list1 and list2:
if list1.val < list2.val:
node = ListNode(list1.val)
p.next = node
p = p.next
list1 = list1.next
else:
node = ListNode(list2.val)
p.next = node
p = p.next
list2 = list2.next
while list1:
node = ListNode(list1.val)
p.next = node
p = p.next
list1 = list1.next
while list2:
node = ListNode(list2.val)
p.next = node
p = p.next
list2 = list2.next
return dummy.next
if __name__ == '__main__':
data1 = [1, 2, 4]
data2 = [1, 3, 4]
clist = LinkList()
list1 = clist.linklist(data1)
list2 = clist.linklist(data2)
merge = Solution()
result = merge.mergeTwoLists(list1, list2)
a = 1
2、使用队列,排序完之后再创建
class Solution(object):
def mergeTwoLists(self, list1, list2):
"""
:type list1: Optional[ListNode]
:type list2: Optional[ListNode]
:rtype: Optional[ListNode]
"""
'''方法二:队列然后再一次性创建'''
helper = []
if not list1 and not list2:
return list1
if not list1 and list2:
return list2
if list1 and not list2:
return list1
while list1 and list2:
if list1.val < list2.val:
p = list1
list1 = list1.next
p.next = None
helper.append(p)
else:
p = list2
list2 = list2.next
p.next = None
helper.append(p)
dummy = ListNode(-1)
k = dummy
while helper:
node = helper.pop(0)
k.next = node
k = k.next
if list1:
k.next = list1
if list2:
k.next = list2
return dummy.next
这个方法利用队列的先进先出先将两个链表的结点按照value值的大小存储起来,然后创建一个亚结点依次链接起来。完整代码如下:
# Definition for singly-linked list.
class ListNode(object):
def __init__(self, val=0, next=None):
self.val = val
self.next = next
# Definition for linklist.
class LinkList(object):
def __init__(self):
self.head = None
def linklist(self, data):
if not data:
return None
head = ListNode(data[0])
p = head
for i in data[1:]:
node = ListNode(i)
p.next = node
p = p.next
return head
# merge
class Solution(object):
def mergeTwoLists(self, list1, list2):
"""
:type list1: Optional[ListNode]
:type list2: Optional[ListNode]
:rtype: Optional[ListNode]
"""
'''方法二:队列然后再一次性创建'''
helper = []
if not list1 and not list2:
return list1
if not list1 and list2:
return list2
if list1 and not list2:
return list1
while list1 and list2:
if list1.val < list2.val:
p = list1
list1 = list1.next
p.next = None
helper.append(p)
else:
p = list2
list2 = list2.next
p.next = None
helper.append(p)
dummy = ListNode(-1)
k = dummy
while helper:
node = helper.pop(0)
k.next = node
k = k.next
if list1:
k.next = list1
if list2:
k.next = list2
return dummy.next
if __name__ == '__main__':
data1 = [1, 2, 4]
data2 = [1, 3, 4]
clist = LinkList()
list1 = clist.linklist(data1)
list2 = clist.linklist(data2)
merge = Solution()
result = merge.mergeTwoLists(list1, list2)
a = 1
注意,使用迭代的两种方法我都用到了哑结点,下面使用到的递归的方法则可以在不用创建哑结点的情况下实现两个有序链表的合并。
方法二: 递归
class Solution(object):
def mergeTwoLists(self, list1, list2):
"""
:type list1: Optional[ListNode]
:type list2: Optional[ListNode]
:rtype: Optional[ListNode]
"""
'''递归'''
if not list1 and not list2:
return list1
if not list1 and list2:
return list2
if list1 and not list2:
return list1
if list1.val<list2.val:
list1.next = self.mergeTwoLists(list1.next, list2)
return list1
else:
list2.next = self.mergeTwoLists(list1, list2.next)
return list2
递归的代码就十分简洁了,就是判断当前两个链表的结点那个最小,然后小的那个结点的next结点则再一次调用自身方法来判断。再一次感叹递归方法的简洁性,好用!