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 方案二
方案二的思路是遍历原链表,依次进行插入操作。插入操作分为两种情况:
- 如果该元素小于x,则将该元素插入到小于x的节点的尾部。
- 如果该元素大于等于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)的解决方案。分隔链表是链表问题中比较典型的题目之一,