阅读目录

  • 题目描述
  • 思路和Python实现


题目描述

输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。

思路和Python实现

【思路1】插入在一个链表中

  • 比较两个链表的元素,将元素小的结点不断插入一个主链表中!具体做法:找到两个链表中头节点值相对更小的链表,将其作为主链表,第二个链表中的元素则不断加入到主链表中。步骤为:主链表定义两个指针,指向两个相邻的元素。当第二个链表中的元素值小于主链表中第二个指针时,将第二个链表的当前元素插入到主链表两个指针指向的元素中间,并调整指针指向
# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回合并后列表
    def Merge(self, pHead1, pHead2): # 传入两个链表的头结点
        if pHead1 is None: # 判断条件
            return pHead2
        if pHead2 is None:
            return pHead1
        
        new_head= pHead1 if pHead1.val < pHead2.val else pHead2 # 选择一个更小的作为先链表头结点
        
        pTemp1=pHead1 # 因为会涉及链表的断开和重新链接,所以分别取指针保存两个头结点数据
        pTemp2=pHead2
        
        if new_head == pTemp1: 
            pTemp1=pTemp1.next # 如果更小的是pTemp1,则将pTemp1后移一个位置,就是new_head后移
        else:
            pTemp2=pTemp2.next
            
        previous_pointer=new_head # 保存 new_head 先前的位置
        
        while pTemp1 and pTemp2: # 循环取出比较 pTmep1 和 pTemp2 中的数据
            if pTemp1.val < pTemp2.val:
                previous_pointer.next=pTemp1
                previous_pointer=pTemp1
                pTemp1=pTemp1.next
            else:
                previous_pointer.next=pTemp2
                previous_pointer=pTemp2
                pTemp2=pTemp2.next
            
        if pTemp1 is None:
            previous_pointer.next=pTemp2
        else:
            previous_pointer.next=pTemp1
        
        return new_head

【思路2】递归写法

  • 先比较两个链表的头结点,把小的一个作为主链表的头结点;还知道两个都是单调递增的,那么主链表的下一个结点,就要通过 不断的比较原先两个链表剩下的结点值得出,这时候就可以调用递归了,因为在选出主链表头结点时,就用过了比较,最后返回主链表头结点即可!
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None


class Solution:
    def Merge(self, pHead1, pHead2):
        if pHead1 is None and pHead2 is None:
            return None
        if pHead1 is None:
            return pHead2
        if pHead2 is None:
            return pHead1
        if pHead1.val < pHead2.val:
            # 因为要满足单调不减规则,哪个节点的值小,谁就是新链表的头结点;
            # 如果pHead1小,那么pHead1作为新的头结点,然后,将pHead1.next和整个pHead2的结点递归
            pHead1.next = self.Merge(pHead1.next, pHead2)
            return pHead1
        else:  # 和上面的原理一样,只是pHead2作为新的节点
            pHead2.next = self.Merge(pHead1, pHead2.next)
            return pHead2

【思路三】创建第三个链表作为转接

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def Merge(self, pHead1, pHead2):
        if not pHead1 and not pHead2:  # pHead1和pHead2链表均不存在
            return None
        if not pHead1:  # pHead1链表不存在
            return pHead2
        if not pHead2:  # pHead2链表不存在
            return pHead1
            
        l3 = ListNode(0)
        l3_head_node = l3 # 新增的链表,不是通过pHead1和pHead2比较得来的其中之一链表
        
        while pHead1 and pHead2:
            if pHead1.val <= pHead2.val: # 如果pHead1 小,则作为l3的下一个结点
                l3.next = pHead1 
                pHead1 = pHead1.next # 移动到pHead1的下一个位置
            else:
                l3.next = pHead2 # 如果pHead2 小,则作为l3的下一个结点
                pHead2 = pHead2.next # 移动到pHead2的下一个位置
            l3 = l3.next # 每次新增一个结点,向后移动一个位置
        if pHead1 is not None: # 如果 pHead1 不为空
        	# 表明pHead2 先被一一添加完,剩下指向将l3的下一个结点指向pHead1的结点即可
            l3.next = pHead1
        else:  # 如果 pHead2 不为空
        	# 表明pHead1 先被一一添加完,剩下指向将l3的下一个结点指向pHead2的结点即可
            l3.next = pHead2
        return l3_head_node.next # 返回l3的新开始的头结点!(因为开始取了0,没有实际意义,真正的链表是从下一个结点开始的)