Sort List
Sort a linked list in O(n log n) time using constant space complexity.
分析:
给链表排序,要求O(nlogn)的时间,O(1)的空间。
链表不是数组,给它排序不能像数组一样可以通过各种下标操作。能够想到的方法也就是(1)通过新建一个有序链表,每次从原来链表中选择一个元素到新的有序链表中去,这是一种插入排序的思想,不过算法复杂度为O(n^2),不满足要求。(2)还有就是使用归并排序。之前也写过LeetCode上的k个链表的合并,如果将链表分解成单个小链表(节点),再进行合并,那么即可得到新的链表。时间复杂度为O(nlogn),满足题目要求。
Python 代码:
class Solution(object):
def sortList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head or not head.next:
return head
'''
利用slow指针和fast指针将链表分成前后两个部分
'''
slow, fast = head, head.next
while fast and fast.next:
fast = fast.next.next
slow = slow.next
t = slow.next
slow.next = None
# 再分别递归的对这两个子链表进行归并
l1 = self.sortList(head)
l2 = self.sortList(t)
# 将两个有序的子链表进行合并并返回
return self.mergeList(l1, l2)
def mergeList(self, l1, l2):
'''
对两个有序的子链表进行合并并返回
'''
if not l1 or not l2:
return l1 or l2
h = p = ListNode(-1)
while l1 and l2:
if l1.val < l2.val:
p.next = l1
l1 = l1.next
else:
p.next = l2
l2 = l2.next
p = p.next
p.next = l1 or l2
return h.next
对应的C++代码:
class Solution {
public:
ListNode* sortList(ListNode* head) {
if(!head || !head->next){
return head;
}
// 利用slow指针和fast指针将链表分成前后两个部分
ListNode * slow = head;
ListNode * fast = head->next;
while(fast && fast->next){
fast = fast->next->next;
slow = slow->next;
}
ListNode * t = slow->next;
slow->next = NULL;
// 再分别递归的对这两个子链表进行归并
ListNode * l1 = sortList(head);
ListNode * l2 = sortList(t);
// 将两个有序的子链表进行合并并返回
return mergeList(l1, l2);
}
ListNode * mergeList(ListNode * l1, ListNode * l2){
// 对两个有序的子链表进行合并并返回
if(!l1 && l2){
return l2;
}else if(l1 && !l2){
return l1;
}
ListNode h = ListNode(-1);
ListNode * p = &h;
while(l1 && l2){
if(l1->val < l2->val){
p->next = l1;
l1 = l1->next;
}else{
p->next = l2;
l2 = l2->next;
}
p = p->next;
}
if(l1){
p->next = l1;
}
if(l2){
p->next = l2;
}
return h.next;
}
};