返回

LeetCode 第 86 题:用一种方法分隔链表,让所有小于 x 的节点出现在大于或等于 x 的节点之前

前端

LeetCode 第 86 题要求我们按照指定值 x 分隔链表,使得所有小于 x 的节点都出现在大于或等于 x 的节点之前。同时,我们需要保持两个分区中每个节点的初始相对位置。

对于这道题,存在着多种解决方法,下面我们将分别介绍两种解法:双指针法和递归法。

双指针法

思路分析:

双指针法使用两个指针:一个指针指向链表的当前节点,另一个指针指向小于 x 的节点的尾节点。

算法步骤如下:

  1. 初始化两个指针:curr 指向链表的头节点,prev 指向 null
  2. 遍历链表,当 curr 不为 null 时,执行以下步骤:
    • 如果 curr.val 小于 x,则将 curr 的下一个节点设置为 prev.next,然后将 prev 指向 curr
    • 否则,将 curr 指向 curr.next
  3. prev.next 设置为 null,将 head 指向 prev.next

代码实现:

def partition(head, x):
    # 初始化两个指针:curr 指向链表的头节点,prev 指向 null。
    curr = head
    prev = None

    # 遍历链表,当 curr 不为 null 时,执行以下步骤:
    while curr:
        # 如果 curr.val 小于 x,则将 curr 的下一个节点设置为 prev.next,然后将 prev 指向 curr。
        if curr.val < x:
            # 将 curr 的下一个节点设置为 prev.next
            curr.next = prev.next
            # 将 prev 指向 curr
            prev.next = curr
            # 将 prev 指向 curr 的下一个节点
            prev = curr

        # 否则,将 curr 指向 curr.next。
        else:
            curr = curr.next

    # 将 prev.next 设置为 null,将 head 指向 prev.next。
    prev.next = None
    head = prev.next

    # 返回 head
    return head

递归法

思路分析:

递归法将链表分成两部分:小于 x 的节点和大于或等于 x 的节点。然后,将这两部分递归地连接起来。

算法步骤如下:

  1. 如果链表为空或链表的第一个节点的值大于或等于 x,则返回链表。
  2. 否则,将链表的第一个节点从链表中移除,并将其连接到小于 x 的节点的链表的尾部。
  3. 将小于 x 的节点的链表和大于或等于 x 的节点的链表递归地连接起来。

代码实现:

def partition(head, x):
    # 如果链表为空或链表的第一个节点的值大于或等于 x,则返回链表。
    if not head or head.val >= x:
        return head

    # 将链表的第一个节点从链表中移除,并将其连接到小于 x 的节点的链表的尾部。
    curr = head
    head = head.next
    curr.next = None

    # 将小于 x 的节点的链表和大于或等于 x 的节点的链表递归地连接起来。
    left = partition(head, x)
    right = partition(curr, x)

    # 将小于 x 的节点的链表和大于或等于 x 的节点的链表连接起来。
    curr.next = right
    head = left

    # 返回 head
    return head