Partition List

来源:互联网 发布:数据挖掘 韩家炜 ppt 编辑:程序博客网 时间:2024/06/08 03:47

Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.

You should preserve the original relative order of the nodes in each of the two partitions.

For example,
Given 1->4->3->2->5->2 and x = 3,
return 1->2->2->4->3->5.


Version1: Using extra memory space.

Analysis: It's straightforward. Just create two lists, small and large. Scan the original list one time and build small and large appropriately. Finally, concatenate small and large and return small.next as the result.  

/** * Definition for singly-linked list. * public class ListNode { *     int val; *     ListNode next; *     ListNode(int x) { *         val = x; *         next = null; *     } * } */public class Solution {    public ListNode partition(ListNode head, int x) {        ListNode large = new ListNode(0);        ListNode curl = large;        ListNode small = new ListNode(0);        ListNode curs = small;        ListNode current = head;                if(head == null) {            return head;        }                if(current.val >= x) {            curl.next = current;            curl = curl.next;        }        else if(current.val < x) {            curs.next = current;            curs = curs.next;        }        while(current.next != null) {            current = current.next;            if(current.val >= x) {                curl.next = current;                curl = curl.next;            }            else if(current.val < x) {                curs.next = current;                curs = curs.next;            }        }                curs.next = large.next;        curl.next = null;        return small.next;    }}


Version2: In place partition

Analysis: First, scan the original list. Let the last node that smaller than x to be the begin node of insertion, while choose the first node that equal or larger than x to be the end node of insertion. After that, scan the rest of the original list, insert into the range defined by the first step if needed. Typically, four pointers are needed, i.e. current, previous, insertBegin and insertEnd. Moreover,newhead, which points to head, is a "fake head" in case that the head of the original list is changed during the operation. In terms of the final result, newhead.next is always returned. Specifically, if the first node is equal or greater than x, the range defined by insertBegin and insertEnd pointers should just between newhead and the first node. However, if the first node is smaller than x, everything is just the same as usual. 

/** * Definition for singly-linked list. * public class ListNode { *     int val; *     ListNode next; *     ListNode(int x) { *         val = x; *         next = null; *     } * } */public class Solution {    public ListNode partition(ListNode head, int x) {        ListNode newhead = new ListNode(0);        newhead.next = head;        ListNode current = newhead.next;        ListNode previous = null;        ListNode insertBegin = newhead;        ListNode insertEnd = null;                if(head == null) {            return head;        }                while(current != null) {            if(insertEnd == null) {                if(current.val >= x) {                    insertEnd = current;                }                else {                    insertBegin = insertBegin.next;                }                previous = current;                current = current.next;            }            else {                if(current.val < x) {                    insertBegin.next = current;                    insertBegin = current;                    previous.next = current.next;                    current.next = insertEnd;                    current = previous.next;                }                else {                    previous = current;                    current = current.next;                }            }        }                return newhead.next;    }}


Update 02/03/2014: 

/** * Definition for singly-linked list. * public class ListNode { *     int val; *     ListNode next; *     ListNode(int x) { *         val = x; *         next = null; *     } * } */public class Solution {    public ListNode partition(ListNode head, int x) {        if(head==null || head.next==null) return head;  // edge case        ListNode newhead = new ListNode(0);        newhead.next = head;                ListNode smaller = newhead;     // points to the last node that smaller than x        while(smaller.next!=null && smaller.next.val<x) {            smaller = smaller.next;        }        if(smaller.next==null) return newhead.next;     // all nodes are smaller than x                ListNode pre = smaller.next;        ListNode cur = pre.next;        while(cur != null) {            if(cur.val < x) {                pre.next = cur.next;                cur.next = smaller.next;                smaller.next = cur;                smaller = cur;                cur=pre.next;            }            else {                pre = cur;                cur = cur.next;            }        }        return newhead.next;    }}


0 0