链表-单链表的分解

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

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

示例 1:

img

输入:head = [1,4,3,2,5,2], x = 3
输出:[1,2,2,4,3,5]
示例 2:

输入:head = [2,1], x = 2
输出:[1,2]


在合并两个有序链表时让你合二为一,而这里需要分解让你把原链表一分为二。具体来说,我们可以把原链表分成两个小链表,一个链表中的元素大小都小于 x,另一个链表中的元素都大于等于 x,最后再把这两条链表接到一起,就得到了题目想要的结果。

整体逻辑和合并有序链表非常相似,细节直接看代码吧,注意虚拟头结点的运用:

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public static ListNode partition(ListNode head, int x) {
// 存放小于 x 的链表的虚拟头结点
ListNode lowDummy = new ListNode(-1);
ListNode low = lowDummy;
// 存放大于等于 x 的链表的虚拟头结点
ListNode highDummy = new ListNode(-1);
ListNode high = highDummy;
// p 负责遍历原链表,类似合并两个有序链表的逻辑
// 这里是将一个链表分解成两个链表
ListNode p = head;
while (p!=null){
if(p.val < x){
low.next = p;
low = low.next;
}else{
high.next = p;
high = high.next;
}
// 断开原链表中的每个节点的 next 指针
ListNode temp = p.next;
p.next = null;
p = temp;
}
// 连接两个链表
low.next = highDummy.next;
return lowDummy.next;
}