86分隔链表,148排序链表,143重排链表,328奇偶链表

86.分隔链表

在这里插入图片描述
新建两个链表,一个储存小于x的一个储存大于等于x的结点,然后拼接

class Solution(object):
    def partition(self, head, x):
        dummy1=ListNode()
        dummy2=ListNode()
        p1,p2=dummy1,dummy2
        while head:
            new=ListNode(head.val)
            if head.val<x:
                p1.next=new
                p1=p1.next
            else:
                p2.next=new
                p2=p2.next
            head=head.next
        p1.next=dummy2.next
        return dummy1.next

148.排序链表

1.归并排序

不断二分链表,至子链表只包含一个或零个节点
然后两两合并升序链表
时间复杂度O(nlogn)空间复杂度O(logn)

class Solution:
	"合并两个升序链表"
    def mergeTwoLists(self,l1,l2):
        dummy=ListNode()
        p=dummy
        while l1 and l2:
            s1,s2=l1.val,l2.val
            if s1<=s2:
                p.next=l1
                p=p.next
                l1=l1.next
            else:
                p.next=l2
                p=p.next
                l2=l2.next
            p.next=l2 if l2 else l1
        return dummy.next
    def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
    	##停止条件##
        if head==None or head.next==None:return head
        ##使用双指针找链表中间节点##
        s,f=head,head.next
        while f and f.next:
            s=s.next
            f=f.next.next
        ##中间断开,分成左右两个子链表##
        mid,s.next=s.next,None
        left, right = self.sortList(head), self.sortList(mid)
        ##归并两个子链表##
        return self.mergeTwoLists(left,right)

2.自下向上归并

思想:首先依次两两节点归并为长度为2的递增链表,然后两两归并长度为2的链表得到若干长为4的链表,再向上归并至原长度。
需要归并logn次每次需要遍历链表,时间复杂度为O(nlogn)
空间复杂度只需要存储几个指针向量,空间复杂度O(1)

class Solution:
    def mergeTwoLists(self,l1,l2):
        dummy=ListNode()
        p=dummy
        while l1 and l2:
            s1,s2=l1.val,l2.val
            if s1<=s2:
                p.next=l1
                p=p.next
                l1=l1.next
            else:
                p.next=l2
                p=p.next
                l2=l2.next
        p.next=l2 if l2 else l1
        while p.next:
            p=p.next
        tail=p
        return dummy.next,tail
    def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
    #记录链表长度#
        len=0
        l=head
        while l:
            len+=1
            l=l.next
        if len<2:return head
        dummy=ListNode(next=head)
        sublen=1
        while sublen<=len:
            tail=dummy
            cur=dummy.next
            while cur:
            	#向前遍历链表,得到长为sublen的两个子序列head1,head2,升序合并#
                head1=cur
                for i in range(sublen-1):
                    if cur.next==None:
                        break
                    cur=cur.next
                head2=cur.next
                cur.next=None
                cur=head2
                #注意断开尾节点,并注意cur遍历到最后为空时的边界#
                if cur!=None:
                    for i in range(sublen-1):
                        if cur.next==None:
                            break
                        cur=cur.next
                    nex=cur.next
                    cur.next=None
                    cur=nex
                    #依次合并长为sublen的子链表,然后与原链表链接#
                    tail.next,tail=self.mergeTwoLists(head1,head2)
                else:
                    tail.next,tail=self.mergeTwoLists(head1,head2)
            sublen<<=1
        return dummy.next

143.重排链表

在这里插入图片描述
从中间断开,将后半部分链表压入栈,然后前半部分链表每隔一个节点连接栈中最后一个元素,时间空间复杂度O(n)
后半部分逆序插入前半部分:同栈,不过空间复杂度O(1)

class Solution:
    def reorderList(self, head: ListNode) -> None:
        if head is None or head.next is None or head.next.next is None:return head
        dummy=ListNode(next=head)
        s,f=dummy,head
        #找中间节点#
        while f and f.next:
            s=s.next
            f=f.next.next
        #从中间断开,后半部分节点数>=前半部分#
        right=s.next
        s.next=None
        left=dummy.next
        #将后半部分的节点压入栈内#
        stack=[]
        while right:
            stack.append(right)
            right=right.next
        #将栈中的节点插入前半部分链表#
        while left:
            new=stack.pop()
            cur=left
            left=left.next
            cur.next=new
            new.next=left
        #栈不为空的情况,将栈中剩余最后一个元素连接到链表尾#
        if stack:
            new.next=stack.pop()
            new=new.next
            new.next=None
        return dummy.next

在这里插入图片描述

328. 奇偶链表

在这里插入图片描述

分别复制奇偶链表,拼接

只储存节点的指针,空间复杂度O(1)

class Solution(object):
    def oddEvenList(self, head):
        if not head:return head
        dummy=ListNode(next=head)
        p=dummy
        dummy2=ListNode(next=head.next)
        p2=dummy2
        ##使用try语句来处理边界##
        try:
            while 1:
                p2.next=head.next
                p2=p2.next
                p.next=head
                p=p.next
                head=head.next.next
        except:
            p.next=dummy2.next
            return dummy.next
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值