Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情。
一、题目
给你一个链表的头节点 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
二、题解
1.解读
简单的说就是需要移动链表的节点,将小于节点值小于x的节点,按原来的顺序移动到左边,其他的就移动到右边。
方法一
需要处理的节点分为两部分,一部分为节点值小于x的所有节点,另外一部分为节点值大于等于x的所有节点。所以可以使用两个链表,[小链表]按原链表的顺序存储所有节点值小于x的节点,[大链表]按原链表的顺序存储所有节点值大于等于x的节点。最后只需要将[小链表]的尾节点指向[大链表]的头结点来连接成一个节点即可。具体的首先新建[小链表]、[大链表]的一个头结点,然后在分别有两个指针指向这两个头结点。然后开始遍历原head链表的节点,如果当前节点值小于x了,就将当前节点连接到[小链表]后面,否则将当前节点连接到[大链表]后面,然后继续遍历head链表其余节点。最后因为[大链表]的节点是指向head链表的节点,为了防止链表循环引用,所以要将[大链表]的尾节点切断,然后再将[小链表]和[大链表]连接起来,返回[小链表]的节点就可以了。
三、代码
方法一 Java代码
class Solution {
public ListNode partition(ListNode head, int x) {
ListNode small = new ListNode(0);
ListNode large = new ListNode(0);
ListNode smallP = small;
ListNode largeP = large;
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 = largeP.next;
return smallP.next;
}
}
时间复杂度:O(n),需要一次遍历链表。
空间复杂度:O(1),需要常数个空间变量。