力扣面试150(54/150)
8.12 86. 分隔链表
给你一个链表的头节点 head
和一个特定值 x
,请你对链表进行分隔,使得所有 小于 x
的节点都出现在 大于或等于 x
的节点之前。
你应当 保留 两个分区中每个节点的初始相对位置。
我的思路:
因为题目说的是所有 小于 x
的节点都出现在 大于或等于 x
的节点之前+ 保留 两个分区中每个节点的初始相对位置,再加上上一题的启发,我就想到了维护两个链表,一个是大于等于x的链表,一个是小于x的链表,然后进行拼接就可以了。
代码看起来很多,但是思想很简单,有几个细节:
首先是关于新建链表的头指针,其实就是判定head的值和x的大小,因为这个方法只能判定一个链表嘛,所以在每次进行判定的时候也要判断头指针是否存在,不存在就要初始化头指针。
其次是最后的拼接啦,因为有很多特殊的情况,在每次next的时候都要判断这个指针在不在,如果有min返回minHead,如果没有min有max就返回maxHead,注意顺序一定不要反。
我的代码:
var partition = function(head, x) {if(!head) return head;let minHead = null;let maxHead = null;let cur = null;let max = null;let min = null;if(head.val >= x){maxHead = head;max = maxHead;}else if(head.val < x){minHead = head;min = minHead;}cur = head.next;while(cur){if(cur.val >= x){if(!max){maxHead = cur;max = maxHead;}else {max.next = cur;max = max.next;}}else {if(!min){minHead = cur;min = minHead;}else {min.next = cur;min = min.next;}}cur = cur.next;}if(max){max.next = null;}if(min){min.next = maxHead;return minHead}else if(max){return maxHead;}// return minHead;
};
总结:
这段代码实现了链表分区功能,将小于给定值x的节点全部移到大于或等于x的节点之前,同时保持两类节点内部的原始相对顺序。代码通过创建两个子链表(minHead和maxHead)分别收集小于x和大于等于x的节点,遍历原链表时根据节点值将其添加到对应子链表末尾。遍历结束后,将min子链表的尾部连接到max子链表的头部,最后根据是否存在min子链表返回合并后的结果(若min子链表不存在则直接返回max子链表)。整个过程通过维护四个指针(minHead/min和maxHead/max)高效完成链表拆分与重组,确保了O(n)时间复杂度和O(1)空间复杂度。