携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情
分隔链表
题目描述:
给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。
你应当 保留 两个分区中每个节点的初始相对位置。
解题思路
思路一: 维护两个链表small 和 large
small 链表按顺序存储所有小于 x 的节点,large 链表按顺序存储所有大于等于 x 的节点。遍历完原链表后,我们只要将 small 链表尾节点指向 large 链表的头节点即能完成对链表的分隔。
- 设 smallHead 和 largeHead 分别为两个链表的哑节点(方便地处理头节点为空的边界条件),即它们的 next 指针指向链表的头节点 ;
- 设 small 和 large 节点指向当前链表的末尾节点。开始时 smallHead=small,largeHead=large
- 从前往后遍历链表,判断当前链表的节点值是否小于 x,如果小于就将 small 的 next 指针指向该节点,否则将 large 的 next 指针指向该节点
- 遍历结束后,我们将 large 的 next 指针置空,这是因为当前节点复用的是原链表的节点,我们需要切断引用;同时将 small 的 next 指针指向 largeHead 的 next 指针指向的节点
- 最后返回 smallHead 的 next
实现代码如下:
/**
* @param {ListNode} head
* @param {number} x
* @return {ListNode}
*/
var partition = function (head, x) {
var small = new ListNode(0);
var smallHead = small;
var large = new ListNode(0);
var 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)