题目:
Sort List
Sort a linked list in O(n log n) time using constant space complexity.
思路:
O(nlogn)+常数空间复杂度,掐指一算,貌似只有快排和堆排。堆排显然太不适合链表。快排我做了很久,始终很难AC。参考别人的答案,猛然大悟,链表的归并空间复杂度是常数的!对链表归并排序并不难。
代码:
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode sortList(ListNode head) {
if(null == head || null == head.next) return head;
ListNode endNode = head;
while(endNode.next != null) endNode = endNode.next;
return sortList(head, endNode);
}
private ListNode sortList(ListNode startNode, ListNode endNode) {
if(startNode == endNode) {
startNode.next = null;
return startNode;
} else {
ListNode front = startNode;
ListNode back = startNode;
while(back != endNode) {
if(endNode == back.next) {
back = back.next;
break;
}
front = front.next;
back = back.next.next;
}
ListNode rightList = sortList(front.next, endNode);
ListNode leftList = sortList(startNode, front);
return mergeNode(leftList, rightList);
}
}
private ListNode mergeNode(ListNode leftNode, ListNode rightNode) {
ListNode head = new ListNode(0);
ListNode curNode = head;
while(leftNode != null && rightNode != null) {
if(leftNode.val < rightNode.val) {
curNode.next = leftNode;
leftNode = leftNode.next;
} else {
curNode.next = rightNode;
rightNode = rightNode.next;
}
curNode = curNode.next;
}
while(leftNode != null) {
curNode.next = leftNode;
leftNode = leftNode.next;
curNode = curNode.next;
}
while(rightNode != null) {
curNode.next = rightNode;
rightNode = rightNode.next;
curNode = curNode.next;
}
curNode.next = null;
return head.next;
}
}
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode sortList(ListNode head) {
if(null == head || null == head.next) return head;
ListNode endNode = head;
while(endNode.next != null) endNode = endNode.next;
return sortList(head, endNode);
}
private ListNode sortList(ListNode startNode, ListNode endNode) {
if(startNode == endNode) {
startNode.next = null;
return startNode;
} else {
ListNode front = startNode;
ListNode back = startNode;
while(back != endNode) {
if(endNode == back.next) {
back = back.next;
break;
}
front = front.next;
back = back.next.next;
}
ListNode rightList = sortList(front.next, endNode);
ListNode leftList = sortList(startNode, front);
return mergeNode(leftList, rightList);
}
}
private ListNode mergeNode(ListNode leftNode, ListNode rightNode) {
ListNode head = new ListNode(0);
ListNode curNode = head;
while(leftNode != null && rightNode != null) {
if(leftNode.val < rightNode.val) {
curNode.next = leftNode;
leftNode = leftNode.next;
} else {
curNode.next = rightNode;
rightNode = rightNode.next;
}
curNode = curNode.next;
}
while(leftNode != null) {
curNode.next = leftNode;
leftNode = leftNode.next;
curNode = curNode.next;
}
while(rightNode != null) {
curNode.next = rightNode;
rightNode = rightNode.next;
curNode = curNode.next;
}
curNode.next = null;
return head.next;
}
}