给你一个链表的头节点 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]
如题所示,我们只需要找出比x小的部分和比x大的部分即可。也就是说我们只需要新建两个链表,small和large,比x小的全部放入small链表中,其余的全部放入large链表中,遍历完全部链表,将small链表的尾部连接到large的头部即可。
我们设立smallHead和largeHead两个哑结点,即他们的指针指向链表的头节点,这样做的目的是更方便地处理头节点为空的边界条件。同时设small和large节点指向当前链表的末尾节点。开始时smallHead = small,largeHead = large。随后,从前往后遍历链表,判断当前链表的节点值是否小于x,如果小于就将small.next指向该节点,否则将large的next指向该节点。
遍历结束后,我们将large.next置空,这样是因为当前节点复用的是原链表的节点,而其next指针可能指向一个小于x的节点, 我们需要切断这个引用。同时将small的next指针指向largeHead的next指针指向的节点,真正意义上的large列表的头节点。最后返回smallHead的next指针,即为所求。
var partition = function(head, x) {
let small = new ListNode(0);
const smallHead = small;
let large = new ListNode(0);
const largeHead = 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 = largeHead.next;
return smallHead.next;
};
复制代码
复杂度分析
- 时间复杂度:O(n),其中n是原链表的长度,我们对该链表进行了一次遍历。
- 空间复杂度:O(1)。