要求
传入一个链表的头节点 head 和一个特定值 x ,需要对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。
思路
假设链表为:1->7->34->2->4->9,x=4
把它们分出来,小于4的是1、2;大于等于4的是7、34、4、9
所以我们需要把传入的链表分开,然后定义两个虚拟头,用来存小于/大于等于4的两个链表,然后再连上,即可得到要求所述的链表
思路图
第一步、
第二步、
第三步、
详细代码
var partition = function (head, x) {
// 当传入的head为空,直接return出去
if (!head) return null;
// 创建两个虚拟头,用来存放稍后判断的节点,创建两个指针,指向两个虚拟头
let big = new ListNode(),
small = new ListNode(),
bigNode = big,
smallNode = small;
// for循环:创建cur指向head,创建一个next,保持每次循环后都把next的值赋给cur
// 创建cur指向head,因为要从链表第一个节点开始判断
// 创建next,因为要防止cur的下一节点丢失,进入for循环后,next指向cur的下一节点
// 当cur不为空时进入for循环
// 每次循环后都进行赋值cur = next
for (let cur = head, next; cur; cur = next) {
// next指针指向cur指针所指的节点的下一节点
next = cur.next;
// 把cur指针所指的节点与下一节点断开
cur.next = null;
// 进行判断,分类
if (cur.val < x) {
// 赋值给我们创建的链表
smallNode.next = cur;
// ①与链表(small)同时创建的指针(smallNode)指向赋值的节点
// ②保存让我们创建的链表(small)的指针(smallNode)一直指向链表的最后一个节点
smallNode = cur;
} else {
// 同①
bigNode.next = cur;
// 同②
bigNode = cur;
}
}
// 把我们创建的两个链表连接上
// 因为与链表(small)同时创建的指针(smallNode)一直指向链表(small)的最后一个节点
// 所以:smallNode.next = big.next
smallNode.next = big.next;
return small.next;
};