分隔链表

104 阅读2分钟

要求

传入一个链表的头节点 head 和一个特定值 x ,需要对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。

思路

假设链表为:1->7->34->2->4->9,x=4

把它们分出来,小于4的是1、2;大于等于4的是7、34、4、9

所以我们需要把传入的链表分开,然后定义两个虚拟头,用来存小于/大于等于4的两个链表,然后再连上,即可得到要求所述的链表

思路图

第一步、

1.png 第二步、

2.png 第三步、

3.png

详细代码


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;
};