/**
* Definition for ListNode.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int val) {
* this.val = val;
* this.next = null;
* }
* }
*/
// quick sort solution
public class Solution {
/**
* @param head: The head of linked list.
* @return: You should return the head of the sorted linked list,
using constant space complexity.
*/
public ListNode sortList(ListNode head) {
ListNode tail = getTail(head);
quickSort(head, tail);
return head;
}
private void quickSort(ListNode head, ListNode tail) {
if (head == null || tail == null || head == tail) return;
if (head == tail.next) return;
// 因为partition后需要不止一个返回值(pivot node, end),我们直接在主函数里实现
// partition
int pivot = head.val;
ListNode left = head;
ListNode left_tail = null;
ListNode right = head.next;
while (right != tail.next) {
if (right.val <= pivot) {
left_tail = left;
left = left.next;
swapValue(left, right);
}
right = right.next;
}
swapValue(left, head);
// recursion
ListNode mid = left;
quickSort(head, left_tail);
quickSort(mid.next, tail);
}
private void swapValue(ListNode a, ListNode b) {
if (a == b) return;
int t = a.val;
a.val = b.val;
b.val = t;
}
private ListNode getTail(ListNode head) {
if (head == null) return null;
while (head.next != null) {
head = head.next;
}
return head;
}
}
class Solution:
"""
@param head: The first node of the linked list.
@return: You should return the head of the sorted linked list,
using constant space complexity.
"""
def sortList(self, head):
if not head or not head.next: return head
mid = self.getMid(head)
right_head = mid.next
mid.next = None
left = self.sortList(head)
right = self.sortList(right_head)
return self.merge(left, right)
def getMid(self, head):
slow = head
fast = head.next
while fast and fast.next:
slow = slow.next
fast = fast.next.next
return slow
def merge(self, left, right):
dummy = ListNode(0)
curr = dummy
while left or right:
if not left:
curr.next = right
break
if not right:
curr.next = left
break
if left.val <= right.val:
curr.next = left
curr = curr.next
left = left.next
else:
curr.next = right
curr = curr.next
right = right.next
return dummy.next
# Quick Sort solution
class Solution:
# 仍然是交换值
def sortList(self, head):
def quickSort(head, tail):
if not head or not tail or tail.next == head:
return head
# do partition first
pivot = head.val
dummy = ListNode(0)
dummy.next = head
left = dummy
right = head
leftTail = dummy
while right != tail.next:
if right.val <= pivot:
leftTail = left
left = left.next
swap(left, right)
right = right.next
swap(left, head)
# 此时的left就是pivot所在位置, leftTail 为前半段的tail
head1 = quickSort(head, leftTail)
head2 = quickSort(left.next, tail)
return head1
def swap(node1, node2):
t = node1.val
node1.val = node2.val
node2.val = t
def getTail(head):
if not head:
return None
while head.next:
head = head.next
return head
# main part
tail = getTail(head)
return quickSort(head, tail)
public class Solution {
/*
* @param head: The head of linked list.
* @return: You should return the head of the sorted linked list, using constant space complexity.
*/
// merge sort solution
public ListNode sortList(ListNode head) {
if (head == null || head.next == null) return head;
ListNode mid = split(head);
ListNode l1 = sortList(head);
ListNode l2 = sortList(mid);
return merge(l1, l2);
}
private ListNode merge(ListNode head1, ListNode head2) {
if (head1 == null) return head2;
else if (head2 == null) return head1;
ListNode dummy = new ListNode(0);
ListNode curr = dummy;
while (head1 != null && head2 != null) {
if (head1.val < head2.val) {
curr.next = head1;
head1 = head1.next;
} else {
curr.next = head2;
head2 = head2.next;
}
curr = curr.next;
}
if (head1 == null) curr.next = head2;
else curr.next = head1;
return dummy.next;
}
// 找到中间偏右的node作为mid,例如 1->2->null,should return 2, 同时断开 1->2
// 精髓就是令fast的起始位置为 slow->next, 这样停止时的 slow 偏左,其右是应该
// 返回的 mid,保存slow.next, 先断开当前slow和next,然后返回其右即可。
private ListNode split(ListNode head) {
if (head == null || head.next == null) return null;
ListNode slow = head;
ListNode fast = slow.next;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
ListNode ret = slow.next;
slow.next = null;
return ret;
}
}
class Solution:
"""
@param: head: The head of linked list.
@return: You should return the head of the sorted linked list, using constant space complexity.
"""
def sortList(self, head):
# ret: <ListNode>
def split(head):
if not head:
return None
slow = head
fast = head.next
while fast and fast.next:
slow = slow.next
fast = fast.next.next
ret = slow.next
slow.next = None
return ret
# ret: <ListNode>
def mergeSort(head):
if not head or not head.next:
return head
mid = split(head)
head1 = mergeSort(head)
head2 = mergeSort(mid)
return merge(head1, head2)
# ret: <ListNode>
def merge(head1, head2):
dummy = ListNode(0)
curr = dummy
while head1 and head2:
if head1.val < head2.val:
curr.next = head1
head1 = head1.next
else:
curr.next = head2
head2 = head2.next
curr = curr.next
if not head1:
curr.next = head2
else:
curr.next = head1
return dummy.next
# Main part:
return mergeSort(head)
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def sortList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head or not head.next:
return head
dummy = ListNode(0)
dummy.next = head
pivot = self.partition(dummy, None)
self.quickSort(dummy, pivot)
self.quickSort(pivot, None)
return dummy.next
def partition(self, preHead, tailNext):
dummy1 = ListNode(0)
dummy2 = ListNode(0)
curr1 = dummy1
curr2 = dummy2
# 如果 preHead 和 tailNext 之间只有一个node, 直接返回
if preHead.next.next is tailNext:
return preHead.next
# 用 preHead.next 作为 pivot,先将其移出
pivot = preHead.next
preHead.next = pivot.next
curr = preHead.next
while curr is not tailNext:
if curr.val <= pivot.val:
curr1.next = curr
curr = curr.next
curr1 = curr1.next
curr1.next = None
else:
curr2.next = curr
curr = curr.next
curr2 = curr2.next
curr2.next = None
# 将 pivot 插入到 dummy2.next 的位置,因为dummy2 都大于 pivot
pivot.next = dummy2.next
dummy2.next = pivot
# 检查如果 dummy2 为空,此时curr2仍然指向dummy2,而我们需要它指向dummy的尾
if curr2 is dummy2:
curr2 = pivot
# 链接两段到原来位置, 分情况考虑一个dummy链表为空的情况
start, end = None, None
if not dummy1.next:
start = dummy2.next
end = curr2
elif not dummy2.next:
start = dummy1.next
end = curr1
else:
start = dummy1.next
end = curr2
curr1.next = dummy2.next
preHead.next = start
end.next = tailNext
return pivot
def quickSort(self, preHead, tailNext):
if preHead is tailNext or preHead.next is tailNext:
return
pivot = self.partition(preHead, tailNext)
self.quickSort(preHead, pivot)
self.quickSort(pivot, tailNext)