这是一道很好的面试题。考察了链表、排序等基本数据结构的使用。同时还融合了递归(分治)的思想。同时分析归并排序的复杂度也不是一件很轻松的事情,值得学习。
1. 题目
2. 分析
本题的难点在于分析时间复杂度和空间复杂度。
3. 代码
3.1 自顶向下的归并排序
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
if head and head.next is None:
return head
if head is None:
return None
# 采用分治的思想解决这道题
head1, head2 = self.split_list(head)
new_head1 = self.sortList(head1)
new_head2 = self.sortList(head2)
new_head = self.merge_two_list(new_head1, new_head2)
return new_head
def split_list(self, head):
head1 = head
slow = fast = head
while(fast.next and fast.next.next):
slow = slow.next
fast = fast.next.next
head2 = slow.next
slow.next = None
return head1, head2
# 合并两个有序链表
def merge_two_list(self, head1, head2):
head = None
if head1.val < head2.val:
head = head1
head1 = head1.next
else:
head = head2
head2 = head2.next
head_bak = head
# 开始衔接两个链表
while(head1 and head2):
if head1.val < head2.val:
head.next = head1
head1 = head1.next
else:
head.next = head2
head2 = head2.next
head = head.next
head.next = None
if(head1):
head.next = head1
if head2:
head.next = head2
return head_bak
上面这个代码的复杂度分别是:
- 时间复杂度:
O(NlogN)
- 空间复杂度:
O(logN)