给定一个链表和一个特定值 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; } }