携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详情
分隔链表
给你一个链表的头节点 head
和一个特定值 x
,请你对链表进行分隔,使得所有 小于 x
的节点都出现在 大于或等于 x
的节点之前。
你应当 保留 两个分区中每个节点的初始相对位置。
示例 1:
输入:head = [1,4,3,2,5,2], x = 3
输出:[1,2,2,4,3,5]
复制代码
示例 2:
输入:head = [2,1], x = 2
输出:[1,2]
复制代码
提示:
- 链表中节点的数目在范围
[0, 200]
内 -100 <= Node.val <= 100
-200 <= x <= 200
解题思路:双指针
题目中要求对链表进行分隔,使得所有 小于
x的节点都出现在 大于或等于
x 的节点之前
,说明我们可以先将链表分成两个小链表,一个小链表用来存小于x
的结点,另一个小链表可以用来存大于等于x
的结点。我们再将这两个链表连接起来,不就完成了分割列表的操作了吗
具体步骤:
- 考虑到链表后续操作能够更方便些,我们这里就用含有虚拟头节点的链表来存储 小于
x
的结点 和 大于等于x
的结点 - 遍历目标链表,将 小于
x
的结点存入p1
中,将 大于等于x
的结点存入p2
中
(这里
p1
指的就是用来存储小于x
的结点的子链表,同理,p2就是用来存储大于等于x
的结点的子链表)
- 遍历完了目标链表后,将
p1
的尾部指针指向p2
的头部元素,完成连接操作
代码:(JAVA)
public ListNode partition(ListNode head, int x) {
//存放小于 x 的链表的虚拟头结点
ListNode temp1 = new ListNode(-1);
//存放大于等于 x 的链表的虚拟头结点
ListNode temp2 = new ListNode(-1);
//p1,p2用来生成结果链表
ListNode p1 = temp1,p2 = temp2;
ListNode res = head;
while (res != null) {
if (res.val < x) {
p1.next = res;
p1 = p1.next;
}else {
p2.next = res;
p2 = p2.next;
}
// 断开原链表中的每个节点的 next 指针
ListNode temp = res.next;
res.next = null;
res = temp;
}
//连接两个链表
p1.next = temp2.next;
return temp1.next;
}
复制代码
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(1)