分隔链表

131 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情

一、题目

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

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

 

示例 1:

输入: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

二、题解

1.解读

简单的说就是需要移动链表的节点,将小于节点值小于x的节点,按原来的顺序移动到左边,其他的就移动到右边。

方法一

需要处理的节点分为两部分,一部分为节点值小于x的所有节点,另外一部分为节点值大于等于x的所有节点。所以可以使用两个链表,[小链表]按原链表的顺序存储所有节点值小于x的节点,[大链表]按原链表的顺序存储所有节点值大于等于x的节点。最后只需要将[小链表]的尾节点指向[大链表]的头结点来连接成一个节点即可。具体的首先新建[小链表][大链表]的一个头结点,然后在分别有两个指针指向这两个头结点。然后开始遍历原head链表的节点,如果当前节点值小于x了,就将当前节点连接到[小链表]后面,否则将当前节点连接到[大链表]后面,然后继续遍历head链表其余节点。最后因为[大链表]的节点是指向head链表的节点,为了防止链表循环引用,所以要将[大链表]的尾节点切断,然后再将[小链表][大链表]连接起来,返回[小链表]的节点就可以了。

三、代码

方法一 Java代码

class Solution {
    public ListNode partition(ListNode head, int x) {
        ListNode small = new ListNode(0);
        ListNode large = new ListNode(0);
        ListNode smallP = small;
        ListNode largeP = large;
        while (head != null) {
            if (head.val < x) {
                small.next = head;
                small = small.next;
            } else {
                large.next = head;
                large = large.next;
            }
            head = head.next;
        }
        large.next = null;
        small.next = largeP.next;
        return smallP.next;
    }
}

时间复杂度:O(n),需要一次遍历链表。

空间复杂度:O(1),需要常数个空间变量。