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

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

示例:

输入: head = 1->4->3->2->5->2, x = 3
输出: 1->2->2->4->3->5

链接:https://leetcode-cn.com/problems/partition-list
思路:整两个全新的节点,一个存放比x小的,一个存放比x大的,然后小的尾巴连上大的头。

class Solution {
    public ListNode partition(ListNode head, int x) {
        if (head == null || head.next == null) {
            return head;//注意这边是return head
        }

         ListNode temp=head;

        ListNode Head_big=new ListNode(-1);
        ListNode Head_big_ptr=Head_big;

        ListNode Head_small=new ListNode(-1);
        ListNode Head_small_ptr=Head_small;

        while (temp!=null)
        {
            if(temp.val<x)
            {
                Head_small_ptr.next=temp;
//                System.out.println(temp.val);
                Head_small_ptr=Head_small_ptr.next;
            }
            else {
                Head_big_ptr.next=temp;
                Head_big_ptr=Head_big_ptr.next;
            }
            temp=temp.next;
        }
        Head_small_ptr.next=Head_big.next;
        Head_big_ptr.next=null;

        ListNode kk=Head_small.next;

        return kk;
    }
}

官方题解:

双指针法:
直觉

我们可以用两个指针before 和 after 来追踪上述的两个链表。两个指针可以用于分别创建两个链表,然后将这两个链表连接即可获得所需的链表。

算法

初始化两个指针 before 和 after。在实现中,我们将两个指针初始化为哑 ListNode。这有助于减少条件判断。(不信的话,你可以试着写一个不带哑结点的方法自己看看!)


利用head指针遍历原链表。
若head 指针指向的元素值 小于 x,该节点应当是 before 链表的一部分。因此我们将其移到 before 中。


否则,该节点应当是after 链表的一部分。因此我们将其移到 after 中。


遍历完原有链表的全部元素之后,我们得到了两个链表 before 和 after。原有链表的元素或者在before 中或者在 after 中,这取决于它们的值。


*`注意:` 由于我们从左到右遍历了原有链表,故两个链表中元素的相对顺序不会发生变化。另外值得注意的是,在图中我们完好地保留了原有链表。事实上,在算法实现中,我们将节点从原有链表中移除,并将它们添加到别的链表中。我们没有使用任何额外的空间,只是将原有的链表元素进行移动。*
现在,可以将 before 和 after 连接,组成所求的链表。


为了算法实现更容易,我们使用了哑结点初始化。不能让哑结点成为返回链表中的一部分,因此在组合两个链表时需要向前移动一个节点。

class Solution {
    public ListNode partition(ListNode head, int x) {

        // before and after are the two pointers used to create the two list
        // before_head and after_head are used to save the heads of the two lists.
        // All of these are initialized with the dummy nodes created.
        ListNode before_head = new ListNode(0);
        ListNode before = before_head;
        ListNode after_head = new ListNode(0);
        ListNode after = after_head;

        while (head != null) {

            // If the original list node is lesser than the given x,
            // assign it to the before list.
            if (head.val < x) {
                before.next = head;
                before = before.next;
            } else {
                // If the original list node is greater or equal to the given x,
                // assign it to the after list.
                after.next = head;
                after = after.next;
            }

            // move ahead in the original list
            head = head.next;
        }

        // Last node of "after" list would also be ending node of the reformed list
        after.next = null;

        // Once all the nodes are correctly assigned to the two lists,
        // combine them to form a single list which would be returned.
        before.next = after_head.next;

        return before_head.next;
    }
}