21.合并两个有序链表

题目

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

示例:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-two-sorted-lists
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

总体来说和合并两个有序数组的思路相同,但代码有很大的区别,比较特别的是python本身没有链表这个结构,也没有相关函数,所以只能去遍历排序。排序的方法有很多,像冒泡排序,快速排序,选择排序。因为链表只有逻辑上的顺序,要交换位置比较麻烦,可以先将结点的数据存入新的数组,将数组排序后重新赋予新的next指向,即相当于数组排序,用于快速排序和冒泡排序等。

一、选择排序

1.递归选择
因为它本身是有序的链表,所以只需要比较链表的第一个元素,将最小的结点选择出来放在第一个,然后用递归的方法选择剩下结点中最小的一个。

#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:
        if l1 == None and l2 == None :
            return None
        elif l1 == None:
            return l2
        elif l2 == None:
            return l1
        elif l1.val < l2.val:
            l1.next = self.mergeTwoLists(l1.next, l2)
            return l1
        else:
            l2.next = self.mergeTwoLists(l1, l2.next)
            return l2

2.迭送选择(指针)
创建一个新链表来存储选择出来的结点,我个人认为这个方法应该是新手最先想到的,因为这种方法是最直接的,但是会考虑不到两个链表长度不同的问题。用指针p(地址)的移动为新的链表添加结点。

class Solution:   
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        phead = ListNode(-1)
        #这里取“-1”是因为下面使用的是p.next
        #p通过循环用p.next来更新自身,p本身只存储p和p.next两个值

        p = phead
        #其实是直接赋予地址,phead的内容随着指针p的更新而更新
        while l1 and l2:
            if l1.val <= l2.val:
                p.next = l1
                l1 = l1.next
            else:
                p.next = l2
                l2 = l2.next            
            p = p.next

        p.next = l1 if l1 is not None else l2
        #补充没有录入的数据

        return phead.next
#phead是从-1开始的,所以要用phead.next使返回值从0开始。
#示例中如果返回的使phead,则返回[-1,1,1,2,3,4,4]
 #排序使从0位置开始的,如果返回值是phead,则返回的数组第一位恒为-1

二、快速排序(数组法)

引用:CSDN博主「Wuhua Jr.」
提交结果为超出内存限制和超出时间限制
在我细读之后我发现可以直接使用list.sort()或者sorted()直接排序,就不需要写快速排序算法

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

class Solution:
    def QuickSortForListNode(stack):
        # 快速排序算法
        # 定义递归返回条件
        if len(stack)<=1:
              return stack
    
        base = stack[0]
        left = []
        right = []
        for x in stack[1:]:       # 分治思想,将不大于基准值的放置左边,将大于基准值的放置右边
            if x.val > base.val:
                right.append(x)
        else:
            left.append(x)
    
        return QuickSortForListNode(left) + [base] + QuickSortForListNode(right)

    def mergeTwoLists(self, pHead1: ListNode, pHead2: ListNode) -> ListNode:
        if pHead1 == None and pHead2 == None:
            return None
        if pHead1 != None and pHead2 == None:
            return pHead1
        if pHead1 == None and pHead2 != None:
            return pHead2
    
        # 首先将两个链表保存到容器中
        stack = []
        cur = pHead1
        while cur:
            stack.append(cur)
            cur = cur.next
            cur = pHead2
        while cur:
            stack.append(cur)
            cur = cur.next
       
        # 使用排序算法进行排序
        # 快速排序
        stack = QuickSortForListNode(stack)
       
    
       # 重新整理排序后链表的每一个节点的next指向
        stack[-1].next = None
        for i in range(len(stack)-1):
            stack[i].next = stack[i+1] 
    
        # 返回链表表头
        return stack[0]
        ————————————————
版权声明:本文为CSDN博主「Wuhua Jr.」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_18254385/article/details/94558439
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值