LeetCode – Sort List:
Sort a linked list in O(n log n) time using constant space complexity.
Analysis
If this problem does not have the constant space limitation, we can easily sort using a sorting method from Java SDK. With the constant space limitation, we need to do some pointer manipulation.
- Break the list to two in the middle
- Recursively sort the two sub lists
- Merge the two sub lists
Java Solution
When I revisit this problem in 2018, I wrote it the following way which is more concise.
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode sortList(ListNode head) { if(head==null || head.next==null){ return head; } //partition the list ListNode p1 = head; ListNode firstEnd = getFirstEnd(head); ListNode p2 = firstEnd.next; firstEnd.next = null; //sort each list p1 = sortList(p1); p2 = sortList(p2); //merge two lists return merge(p1, p2); } //get the list partition point private ListNode getFirstEnd(ListNode head){ ListNode p1 = head; ListNode p2 = head; while(p1!=null && p2!=null){ if(p2.next==null||p2.next.next==null){ return p1; } p1 = p1.next; p2 = p2.next.next; } return head; } //merge two list private ListNode merge(ListNode n1, ListNode n2){ ListNode head = new ListNode(0); ListNode p = head; ListNode p1 = n1; ListNode p2 = n2; while(p1!=null && p2!=null){ if(p1.val<p2.val){ p.next = p1; p1 = p1.next; }else{ p.next = p2; p2 = p2.next; } p = p.next; } if(p1!=null){ p.next = p1; } if(p2!=null){ p.next = p2; } return head.next; } } |
Iterative and Recursive approach: http://javabypatel.blogspot.in/2015/12/merge-sort-linked-list.html
http://www.codeitt.com/linked-lists-in-detail/
Works fine if you change int count = 0; with int count = 1;
it is the same since p1.val == p2. val
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
This line
pNew.next.next = new ListNode(p1.val);
Should be
pNew.next.next = new ListNode(p2.val);
maybe newHead is not nessary.
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;
}
I’m getting stack overflow error for size of length greater than 3.
Definitely not correct. You are creating new nodes.
It’s not correct if you consider the space used by call stack.