Partition List

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;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值