LeetCode – Sort List (Java)

LeetCode - Sort List:

Sort a linked list in O(n log n) time using constant space complexity.

Keys for solving the problem

  1. Break the list to two in the middle
  2. Recursively sort the two sub lists
  3. Merge the two sub lists

This is my accepted answer for the problem.

package algorithm.sort;
 
class ListNode {
	int val;
	ListNode next;
 
	ListNode(int x) {
		val = x;
		next = null;
	}
}
 
public class SortLinkedList {
 
	// merge sort
	public static ListNode mergeSortList(ListNode head) {
 
		if (head == null || head.next == null)
			return head;
 
		// count total number of elements
		int count = 0;
		ListNode p = head;
		while (p != null) {
			count++;
			p = p.next;
		}
 
		// break up to two list
		int middle = count / 2;
 
		ListNode l = head, r = null;
		ListNode p2 = head;
		int countHalf = 0;
		while (p2 != null) {
			countHalf++;
			ListNode next = p2.next;
 
			if (countHalf == middle) {
				p2.next = null;
				r = next;
			}
			p2 = next;
		}
 
		// now we have two parts l and r, recursively sort them
		ListNode h1 = mergeSortList(l);
		ListNode h2 = mergeSortList(r);
 
		// merge together
		ListNode merged = merge(h1, h2);
 
		return merged;
	}
 
	public static ListNode merge(ListNode l, ListNode r) {
		ListNode p1 = l;
		ListNode p2 = r;
 
		ListNode fakeHead = new ListNode(100);
		ListNode pNew = fakeHead;
 
		while (p1 != null || p2 != null) {
 
			if (p1 == null) {
				pNew.next = new ListNode(p2.val);
				p2 = p2.next;
				pNew = pNew.next;
			} else if (p2 == null) {
				pNew.next = new ListNode(p1.val);
				p1 = p1.next;
				pNew = pNew.next;
			} else {
				if (p1.val < p2.val) {
					// if(fakeHead)
					pNew.next = new ListNode(p1.val);
					p1 = p1.next;
					pNew = pNew.next;
				} else if (p1.val == p2.val) {
					pNew.next = new ListNode(p1.val);
					pNew.next.next = new ListNode(p1.val);
					pNew = pNew.next.next;
					p1 = p1.next;
					p2 = p2.next;
 
				} else {
					pNew.next = new ListNode(p2.val);
					p2 = p2.next;
					pNew = pNew.next;
				}
			}
		}
 
		// printList(fakeHead.next);
		return fakeHead.next;
	}
 
	public static void main(String[] args) {
		ListNode n1 = new ListNode(2);
		ListNode n2 = new ListNode(3);
		ListNode n3 = new ListNode(4);
 
		ListNode n4 = new ListNode(3);
		ListNode n5 = new ListNode(4);
		ListNode n6 = new ListNode(5);
 
		n1.next = n2;
		n2.next = n3;
		n3.next = n4;
		n4.next = n5;
		n5.next = n6;
 
		n1 = mergeSortList(n1);
 
		printList(n1);
	}
 
	public static void printList(ListNode x) {
		if(x != null){
			System.out.print(x.val + " ");
			while (x.next != null) {
				System.out.print(x.next.val + " ");
				x = x.next;
			}
			System.out.println();
		}
 
	}
}

Output:

2 3 3 4 4 5
Category >> Algorithms  
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
<pre><code> 
String foo = "bar";
</code></pre>

  1. Wei Qiu on 2014-3-10

    It’s not correct if you consider the space used by call stack.

  2. Lister on 2014-3-30

    Definitely not correct. You are creating new nodes.

  3. Raghav on 2014-4-22

    I’m getting stack overflow error for size of length greater than 3.

  4. tia on 2014-5-13

    A little bit change to merge function works. Create extra nodes is unnecessary

    public ListNode merge(ListNode l, ListNode r){

    ListNode lp = l, rp = r;

    ListNode newhead = new ListNode(-1);

    ListNode cur = newhead;

    while(lp!=null || rp!=null){

    if(lp==null){

    cur.next = rp;

    break;

    }else if(rp==null){

    cur.next = lp;

    break;

    }else{

    if(lp.val <= rp.val){

    cur.next = lp;

    lp = lp.next;

    cur = cur.next;

    }else {

    cur.next = rp;

    rp = rp.next;

    cur = cur.next;

    }

    }

    }

    return newhead.next;

    }

  5. anchao1987 on 2014-5-29

    maybe newHead is not nessary.

  6. Frank on 2014-6-3

    This line
    pNew.next.next = new ListNode(p1.val);

    Should be

    pNew.next.next = new ListNode(p2.val);

  7. Neel Sheyal on 2014-7-2

    If the list is empty or only one element in it, then return the list.
    Divide the linked list into two parts.
    Sort these two parts recursively.
    Merge the sorted parts.

    For explanation and code http://www.algoqueue.com/algoqueue/default/view/851968/merge-sort-on-linkedlist

  8. henrycan1414 on 2014-7-17

    it is the same since p1.val == p2. val

  9. Arnaud Hebert on 2015-4-20

    Works fine if you change int count = 0; with int count = 1;

  10. Saikiran Narlapuram on 2015-12-22
  11. Jayesh on 2015-12-29

Leave a comment

*