剑指off,面试题25:合并两个排序的链表

题目:输入两个递增排序的链表,合并这两个链表,并使新链表中的结点仍然是递增排序的

示例:

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

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

解题思路:

  1、因为输入的两个链表均是有序递增的,所以很容易想到引入两个指针l1, l2分别指向两个链表,根据l1.val,l2.val的大小关系确定结点添加顺序,两指针交替前进,直至遍历结束。

  2、引入头结点:因为初始状态时,合并链表没有头结点,导致循环遍历的时候无法将结点添加到合并链表中,所以我们需要初始化一个头结点作为合并链表的头结点,并将1中遍历得到的结点添加到该头结点后面。

算法流程:

  1、初始化: 头结点:dum,指针cur指向头结点dum

  2、循环合并:当l1或l2为空时跳出:

        1、如果l1.val < l2.val,cur指向l1,cur.next = l1,l1向前走一步,l1 = l1.next

        2、如果l1.val > l2.val,cur指向l2,cur.next = l2, l2向前走一步, l2 = l2.next

        3、cur向前走一步,cur = cur.next

  3、合并剩余尾部:循环跳出有两种情况:l1为空或l2为空:

        1、当l1为空时,将l2添加到cur指向的结点后面

        2、当l2为空时,将l1添加到cur指向的结点后面

  4、返回值:因为合并链表在头结点dum后面,所以返回dum.next

# Definition for singly-linked list.
#class ListNode:
#     def __init__(self, x):
#        self.val = x
#         self.next = None

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        # 一个用来标注起始点
        # 一个用来移动
        '''
         # 非递归
        dum = cur = ListNode(0)
        while l1 and l2:
            if l1.val > l2.val:
                cur.next, l2 = l2, l2.next
            else:
                cur.next, l1 = l1, l1.next
            cur = cur.next
        cur.next = l1 if l1 else l2
        return dum.next
        '''
       # 递归
        if not l1:
            return l2
        if not l2:
            return l1
        dum = cur = ListNode(0)
        if l1.val < l2.val:
            cur.next = l1
            l1.next = self.mergeTwoLists(l1.next, l2)
        else:
            cur.next = l2
            l2.next = self.mergeTwoLists(l1, l2.next)
        return dum.next 

参考:https://leetcode-cn.com/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/solution/mian-shi-ti-25-he-bing-liang-ge-pai-xu-de-lian-b-2/

原文地址:https://www.cnblogs.com/aniu-caili/p/12742833.html