[路飞]_程序员必刷力扣题: 86. 分隔链表

172 阅读2分钟

「这是我参与12月更文挑战的第20天,活动详情查看:2021最后一次更文挑战

86. 分隔链表

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

你应当 保留 两个分区中每个节点的初始相对位置。

示例 1:

image.png

输入: head = [1,4,3,2,5,2], x = 3
输出:[1,2,2,4,3,5]

示例 2:

输入: head = [2,1], x = 2
输出:[1,2]

提示:

  • 链表中节点的数目在范围 [0, 200] 内
  • -100 <= Node.val <= 100
  • -200 <= x <= 200

一次遍历

思路

按照题意我们需要将链表中的中间值x的小的放在x的左边,比x大的放在x的右边

这里我们声明了两个拥有虚拟头结点的链表minList和maxList,这样就可以省去处理一些额外的边界条件,同时声明两个指针minLast和maxList分别指向两个链表的尾结点,方便进行链表的拼接

我们维护这两个链表,minList用来保存比x小的节点,maxList用来保存比x大的节点,

开始遍历,处理每一个遇到的节点node:

  • 如果节点的值val大于x那么我们将它拼接在maxList的末尾,同时每次更新maxList指向末尾节点
  • 如果节点的值val小于x那么我们将它拼接在minList的末尾,同时每次更新minList指向末尾节点

遍历完毕后所有节点自动分配到两个链表之中,接下来我们需要将两个链表衔接起来。因为两个链表都拥有一个虚拟节点,此时只需要让minList的next指向maxList的next,即minLast.next = maxList.next

拼接完毕后我们还要记得处理一下maxLast的next指针一定要为null

返回minList的下一个节点next得到我们的答案

var partition = function (head, x) {
    var minList = new ListNode('min')
    var minLast = minList
    var maxList = new ListNode('max')
    var maxLast = maxList
    var newHead = head
    while (newHead) {
        if (newHead.val < x) {
            minLast.next = newHead
            minLast = newHead
        } else {
            maxLast.next = newHead
            maxLast = newHead
        }
        newHead = newHead.next
    }
    minLast.next = maxList.next
    maxLast.next = null

    return minList.next
};