LeetCode 分隔链表

53 阅读2分钟

LeetCode 分隔链表

分隔链表(Partition List)是一道LeetCode中的问题,要求将一个链表中的元素按照某个特定的值分为两部分,使得满足特定值之前的元素都小于该值,特定值之后的元素都大于等于该值。本文将详细介绍该问题的解决方案。

1. 题目描述

LeetCode中该问题的描述如下:

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

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

示例如下:

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

输出: 1->2->2->4->3->5

2. 解决方案

对于该问题,我们可以想到两种解决方案。

2.1 方案一

方案一的思路是新建两个链表,分别保存小于x和大于等于x的节点。遍历原链表,将元素根据大小插入不同的链表。最后将两个链表拼接起来即可。示例代码如下:

public ListNode partition(ListNode head, int x) {
    ListNode smallHead = new ListNode(0);
    ListNode small = smallHead;
    ListNode largeHead = new ListNode(0);
    ListNode large = largeHead;
    while (head != null) {
        if (head.val < x) {
            small.next = head;
            small = small.next;
        } else {
            large.next = head;
            large = large.next;
        }
        head = head.next;
    }
    large.next = null;
    small.next = largeHead.next;
    return smallHead.next;
}

在该代码中,我们新建了两个链表smallHead和largeHead。这两个链表分别表示小于x和大于等于x的节点。之后遍历原链表,将元素根据大小插入不同的链表中。最后将两个链表拼接起来就完成了分隔链表的操作。

2.2 方案二

方案二的思路是遍历原链表,依次进行插入操作。插入操作分为两种情况:

  1. 如果该元素小于x,则将该元素插入到小于x的节点的尾部。
  2. 如果该元素大于等于x,则将该元素插入到大于等于x的节点的尾部。

代码示例如下:

public ListNode partition(ListNode head, int x) {
    ListNode dummyHead = new ListNode(0);
    dummyHead.next = head;
    ListNode p = dummyHead; // p表示小于x的节点的尾部
    ListNode q = dummyHead; // q表示大于等于x的节点的尾部
    while (q.next != null) {
        if (q.next.val < x) {
            ListNode tmp = p.next;
            p.next = q.next;
            q.next = q.next.next;
            p.next.next = tmp;
            p = p.next;
        } else {
            q = q.next;
        }
    }
    return dummyHead.next;
}

在这段代码中,我们先新建一个节点dummyHead,该节点的下一个节点即为原链表的头节点。之后,我们用p和q两个指针遍历链表,不断进行插入操作。

值得注意的是,在其中的插入操作时,我们需要将原链表中的节点删除,并将该节点插入到新链表中。同时,需要记录小于x的节点和大于等于x的节点的尾部,以方便后续的操作。

3. 总结

本文通过两种不同的示例代码,详细介绍了分隔链表(Partition List)的解决方案。分隔链表是链表问题中比较典型的题目之一,