86 - 分隔链表 - python

104 阅读2分钟

给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。

你应当保留两个分区中每个节点的初始相对位置

示例:

输入: head = 1->4->3->2->5->2, x = 3
输出: 1->2->2->4->3->5

根据题目可知,最后的链表中所有小于 x 的节点都在大于或等于 x 的节点之前,而且必须保留元素之间的相对关系。例如对于1->4->3->2->5->2来说,分隔的变化过程为: [1] -> [1,4] -> [1,4,3] -> [1,2,4,3] -> [1,2,2,4,3] -> [1,2,2,4,3,5]

最终链表可以看作是在保留相关位置关系的基础上的两个链表的链接,其中一个是大于或等于x的元素组成的链表,另一个是小于x的元素组成的链表。因此,一种很自然的想法就是:我们可以新建两个链表beforeHeadafterHead分别存放两部分的元素,最后将afterHead链接到beforeHead后面即可。


在这里插入图片描述
在这里插入图片描述

AC code

class Solution:
    def partition(self, head: ListNode, x: int) -> ListNode:

        # 双链表法
        beforeHead = ListNode(0)
        afterHead = ListNode(0)

        a, b = afterHead, beforeHead
        while head:
            if head.val >= x:
                a.next = head
                a = a.next
            else:
                b.next = head
                b = b.next
            head = head.next

        a.next = None
        b.next =  afterHead.next

        return beforeHead.next

除了双链表法之外,我们使用额外的单链表同样可以实现。首先新建链表newHead用于保存大于或等于x的元素,同时设置指针afterbefore指向新结点,cur指向给定链表的头结点。从头遍历链表:

  • 如果cur.val >= x ,则将其链接到newHead右端,同时更新aftercur

  • 如果cur.val < x

    • 如果它是第一个小于x的元素,则将其链接到newHead左端,同时更新curbefore,另外为了最后结果的输出,这里设置一个新指针r指向当前结点
    • 否则将其插入到newHead前面,同时更新curbefore注意此时r不改变
  • 当链表遍历结束后:

    • 如果 r == None,说明链表中不存在小于x的元素,返回newHead.next
    • 否则执行before.next = newHead.next,返回r

整个算法流程如下所示:
在这里插入图片描述
在这里插入图片描述

AC code

class Solution:
    def partition(self, head: ListNode, x: int) -> ListNode:

        newHead = ListNode(-1)
        before = newHead
        after = newHead
        cur = head
        r = None
        while cur:
            if cur.val >= x:
                after.next= ListNode(cur.val)
                after = after.next
            else:
                node = ListNode(cur.val)
                if newHead == before:
                    node.next = before
                    before = node
                    r = before
                else:
                    node.next = newHead
                    before.next = node
                    before = before.next
            cur = cur.next

        if r:
            before.next = newHead.next
            return r
        else:
            return newHead.next