leetcode 147(用链表实现插入排序) & 148(使用O(n log n)的时间复杂度对链表排序---归并排序)

147 问题描述:根据数组插入排序的思想实现链表的排序

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

class Solution:
    def insertionSortList(self, head: ListNode) -> ListNode:
        # 首先设置一个虚拟结点p(过程当中会更新),cur从head开始向后走,指定一个val(即cur后面的数)。如果val前面的数即cur的值
        # 都小于val,说明不用重排,cur继续向前走,如果val大于cur则从结点p(p随时更新,经过一次重排后,记录的是小于刚才重排
        # 前val的最后一个值,或者说p后面一个数的值会大于重排前val)向后遍历,直到发现大于val,然后重排
        # p也是在一直变化的,有时需要将其重置为虚拟节点,有时不需要
        dummy = ListNode(-1)
        dummy.next = head
        p = dummy
        cur = head
        while cur and cur.next:
            val = cur.next.val # 插入排序从第二个数开始循环,val即第二个数的值
            if cur.val < val:  # 默认val前都是排好序的,cur(val前面一个数)的值都小于val说明cur可以继续向后走
                cur = cur.next
                continue   # 结束该步循环,直到发现cur的值大于val才不进入当前循环,进行下面的重排操作
            
            
            if p.next.val > val:  # 经过若干轮重排后,p可能走到中间某个位置,如果该位置下个数都小于val,p就不需要从dummy开始遍历,从当前位置遍历即可,即从下面while开始更改p的值,相反,p则要重新改成dummy,重头开始遍历
                p = dummy
            
            while p.next.val < val:  # 当p.next的值大于val说明已经发现需要插入的位置了,可以结束循环
                p = p.next           # 当p.next的值小于val时,p需要继续向后走,直到找到需要插入的位置
            
            new = cur.next   # 重排过程
            cur.next = new.next  # 重排过程
            new.next = p.next   # 重排过程
            p.next = new       #重排过程
        return dummy.next
            

148 问题描述:使用O(n log n)的时间复杂度对链表进行排序
解题思路:和数组中的归并排序相似。但在划分左右两边时有所不同。数组中左右两边大致均分。链表中先初始化一个slow=head,fast = head.next,然后每次fast向后走两步,slow向后走一步,因此slow和fast总是相隔一个中间的second。因此左边的数为从head到second(不包括second),右边为second(即右边的head)到最后一个数,然后进行重新排序。

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

class Solution:
    def sortList(self, head: ListNode) -> ListNode:

        if not head or not head.next:  #为空或只有一个数,则直接返回head
            return head
        # divide list into two parts
        fast, slow = head.next, head
        while fast and fast.next:
            fast = fast.next.next
            slow = slow.next
        second = slow.next
        # cut down the first part
        slow.next = None

        l = self.sortList(head)
        r = self.sortList(second)
#         return self.merge(l, r)

#     # merge in-place without dummy node        
#     def merge(self, l, r):
        if not l or not r:
            return l or r
        if l.val > r.val:
            l, r = r, l
        # get the return node "head"
        head = pre = l
        l = l.next
        while l and r:
            if l.val < r.val:
                l = l.next
            else:
                nxt = pre.next
                pre.next = r
                tmp = r.next
                r.next = nxt
                r = tmp
            pre = pre.next
        # l and r at least one is None
        pre.next = l or r
        return head
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱编程的喵喵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值