Partitioning a linked list

折月煮酒 提交于 2019-12-08 18:25:29

I think you can do it in a simpler way:

  • Keep 2 lists, one for lower nodes and other for greater nodes.
  • Iterate the list adding the nodes to the corresponding list.
  • Concatenate the lower list with greater list

Something like this:

public ListNode Partition(ListNode head, int x)
{
    ListNode lowerHead = null, lowerTail = null;              //Head and Tail of lower list
    ListNode greaterHead = null, greaterTail = null;          //Head and Tail of greater list

    ListNode current = head;

    while (current != null)
    {
        if (current.val < x)
        {
            if (lowerHead == null) lowerHead = current;      //If is the first node in the list
            if (lowerTail == null) lowerTail = current;      //set the head an tail to the same value
            else lowerTail = lowerTail.next = current;       //Otherwise, add the node and update the tail
        }
        else
        {
            if (greaterHead == null) greaterHead = current;  //If is the first node in the list
            if (greaterTail == null) greaterTail = current;  //set the head an tail to the same value
            else greaterTail = greaterTail.next = current;   //Otherwise, add the node and update the tail
        }

        current = current.next;
    }

    if (greaterHead != null)
        greaterTail.next = null;

    if (lowerHead == null) return greaterHead;
    else
    {
        lowerTail.next = greaterHead;
        return lowerHead;
    }
} 

Order is preserved since nodes are added as they appear in the original list

It can be done in place, in O(N) time O(1) space. Just keep track of the immediate preceding node, before the first node, that is greater than or equal to the X.

This node acts as the boundary between the nodes that are less than X and nodes that are greater than or equal to X.

Refer the code along with inline comments.

    class Solution {
    public ListNode partition(ListNode head, int x) {
        // Assume that list has at least one instance of X and x = 3

        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        ListNode prev = dummy;
        ListNode curr = head;

        // Keeps track of the preceding node, before the first value greater than or equal to x.
        ListNode large = null;
        // Tracks weather the first node greater than or equal to x has been found.
        boolean isFirstLargeFound = false;

        while(curr != null) {
            if (curr.val >= x) {
                if (!isFirstLargeFound) {
                    large = prev;
                    isFirstLargeFound = true;    
                }
            } else if (isFirstLargeFound) {
                // If the current value is less than x and the first larger value has
                // been found, we need to swap the nodes.
                //
                // Consider the example: 1->4->0->3->2->5, the curr node is at value 0.
                // At this point of time the first larger value i.e. 4 has been already
                // found, hence we have to move the Node with value 0 to a place before 
                // the node with value 4.
                //
                // Before: 1->4->0->3->2->5
                // After: 1->0->4->3->2->5
                ListNode temp = large.next;
                prev.next = curr.next;
                large.next = curr;
                // Ensures that the first element that is >=X, is always next of large node.
                curr.next = temp;
                large = large.next;
            }

            prev = curr;
            curr = curr.next;
        }
        return dummy.next;
    }
}

I solved it in Python and works fine.

current = runner = ll.head
while runner:
    if runner.value < part:
        temp = current.value
        current.value = runner.value
        runner.value = temp

        current = current.next
        runner = runner.next
    else:
        runner = runner.next
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!