分割链表(力扣第86题)
-
给你一个链表的头节点
head
和一个特定值x
,请你对链表进行分隔,使得所有 小于x
的节点都出现在 大于或等于x
的节点之前。你应当 保留 两个分区中每个节点的初始相对位置。
* 一个链表中的元素大小都小于 x,另一个链表中的元素都大于等于 x,
* 最后再把这两条链表接到一起,就得到了题目想要的结果。
*/
class Solution {
public ListNode partition(ListNode head, int x) {
//存放节点大于等于x的值的虚拟头结点
ListNode dummy1 = new ListNode(-1);
//存放节点小于x值的虚拟头结点
ListNode dummy2 = new ListNode(-2);
ListNode p = head;
ListNode p1 = dummy1;
ListNode p2 = dummy2;
while (p != null) {
if (p.val >= x) {
p1.next = p;
p1 = p1.next;
}else{
p2.next = p;
p2 = p2.next;
}
// 这里是先把原来的链表断开,然后再将p后移
// 如果 直接写 p = p.next 的话,结果会形成一个闭环。
// 具体可参考 https://labuladong.online/algo/essential-technique/linked-list-skills-summary/#单链表的分解
ListNode temp = p.next;
p.next = null;
p = temp;
}
//连接两个链表
p2.next = dummy1.next;
return dummy2.next;
}
}
总的来说,如果我们需要把原链表的节点接到新链表上,而不是 new 新节点来组成新链表的话,那么断开节点和原链表之间的链接可能是必要的。那其实我们可以养成一个好习惯,但凡遇到这种情况,就把原链表的节点断开,这样就不会出错了。