leetcode 148.排序链表

题目:

给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。

题目示例:

输入:head = [4,2,1,3]
输出:[1,2,3,4]
输入:head = [-1,5,3,4,0]
输出:[-1,0,3,4,5]
输入:head = []
输出:[]

进阶:你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?

代码(进阶-迭代)

class Solution:
    def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        #迭代
        listlength=1 #归并长度
        dummynode=ListNode()
        dummynode.next=head#哨兵
        h=head
        listnodelength=0
        while h: #统计链表长度
            listnodelength+=1 
            h=h.next
        while listlength<listnodelength: #当归并长度小于链表长度时进行归并
            pre,h=dummynode,dummynode.next#pre是用来迭代新归并链表的,同时用于链接新的节点
            while h:#当前节点有值,h是当前遍历节点
                left=h#左边归并头节点
                count=listlength
                while h and count:#保证节点有值
                    h=h.next
                    count-=1
                if count:
                    break #没有右边归并
                right=h#右边归并头节点
                count=listlength
                while h and count:
                    h=h.next
                    count-=1
                leftcount,rightcount=listlength,listlength-count
                while leftcount and rightcount:#进行归并,不能以链表,因为左右相连
                    if left.val<right.val:
                        pre.next=left
                        left=left.next
                        leftcount-=1
                    else:
                        pre.next=right
                        right=right.next
                        rightcount-=1
                    pre=pre.next
                if leftcount:
                    pre.next=left    
                else:
                    pre.next=right#归并后合并
                while leftcount>0 or rightcount>0:#递归完当前长度
                    pre=pre.next
                    leftcount-=1
                    rightcount-=1
                pre.next=h#当前链表的下一个节点是下一个归并排序的头节点
            listlength*=2
        return dummynode.next

代码逻辑:

因为题目进阶要求我们使用常数级空间复杂度,此时不能用递归,采用迭代方式,直接进行归并

归并思路,从长度为1开始,当归并长度大于等于链表长度说明归并完成

设置dummynode哨兵节点,pre前序指针,h遍历指针来进行操作,

其中Left指针指向左归并序列,right指向右归并序列

需要注意的点是,要注意当前归并序列是否满足归并长度,进行对应设置

在这里考虑用leftcount以及rightcount代表左右归并序列长度

代码(归并递归)

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if not head or not head.next:return head#单节点或者不存在,结束分裂
        slow,fast=head,head.next#快慢指针找中间值
        while fast and fast.next:
            slow=slow.next
            fast=fast.next.next
        mid=slow.next#中间值为慢指针的下一位
        slow.next=None#断开
        left,right=self.sortList(head),self.sortList(mid)#进行递归分解
        dummynode=pre=ListNode()#定义哨兵节点
        while left and right:#分解结束后回溯链接
            if left.val<right.val:
                pre.next=left
                left=left.next
            else:
                pre.next=right
                right=right.next
            pre=pre.next
        pre.next=left if left else right
        return dummynode.next#返回头节点

代码逻辑:

在这里我们主要使用快慢指针进行链表的分解,快指针一次走两步,慢指针一次走一步

同时在合并时用哨兵节点记录我们当前的节点

时间复杂度O(nlogn)空间复杂度(logn)

代码(快排递归)NOAC因为在面对正序或者逆序,时间复杂度O(N2)

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        start=ListNode()#初始化节点
        start.next=head#指向初始节点
        hashmap={}#字典
        count=-1
        while start.next!=None:
            count+=1#索引值
            hashmap[count]=start.next
            start=start.next
        def partition(hashmap,left,right):
            tmp=hashmap[left]
            while left<right:
                while left<right and hashmap[right].val>=tmp.val:
                    right-=1
                hashmap[left]=hashmap[right]
                while left<right and hashmap[left].val<=tmp.val:
                    left+=1
                hashmap[right]=hashmap[left]
            hashmap[left]=tmp
            return left
        def quicksort(hashmap,left,right):
            if left<right:
                mid=partition(hashmap,left,right)
                quicksort(hashmap,left,mid-1)
                quicksort(hashmap,mid+1,right)
        quicksort(hashmap,0,count)
        start=ListNode()
        current=start
        for i in range(count+1):
            current.next=hashmap[i]
            current=current.next
        current.next=None
        return start.next

  • 18
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值