Description: Given the head
of a linked list, return the list after sorting it in ascending order.
Follow up: Can you sort the linked list in O(n logn)
time and O(1)
memory (i.e. constant space)?
Link: 148. Sort List
Examples:
Example 1:
Input: head = [4,2,1,3] Output: [1,2,3,4] Example 2:
Input: head = [-1,5,3,4,0] Output: [-1,0,3,4,5] Example 3: Input: head = [] Output: []
思路: 我们比较熟悉数组的排序,那么我们就先保存链表的值到arr, 用归并排序对数组arr实现排序,然后在将排好的数值赋值到链表。
class Solution(object): def sortList(self, head): """ :type head: ListNode :rtype: ListNode """ if not head or not head.next: return head p = head arr = [] while p: arr.append(p.val) p = p.next new = self.merge_sort(arr) p = head while new: p.val = new.pop(0) p = p.next return head def merge_sort(self, arr): if len(arr) == 1: return arr mid = len(arr) // 2 left = arr[:mid] right = arr[mid:] return self.merge(self.merge_sort(left), self.merge_sort(right)) def merge(self, left, right): result = [] while len(left) > 0 and len(right) > 0: if left[0] <= right[0]: result.append(left.pop(0)) else: result.append(right.pop(0)) result += left result += right return result
虽然归并排序的时间复杂度是符合的,但是我们两次遍历链表,并保存arr,时间和空间的浪费很大,现在来改一改。把对arr的操作改成对链表的,那么最重要的就是找到arr中的mid,链表怎么找?快慢指针,快指针每次走两步,慢指针走一步,当快指针走到结尾的之后,慢指针刚好在中间。
class Solution(object): def sortList(self, head): """ :type head: ListNode :rtype: ListNode """ if not head or not head.next: return head pre, slow, fast = head, head, head while fast and fast.next: pre = slow slow = slow.next fast = fast.next.next pre.next = None left = self.sortList(head) right = self.sortList(slow) return self.merge(left, right) def merge(self, left, right): head = ListNode(0) move = head while left and right: if left.val <= right.val: move.next = left left = left.next else: move.next = right right = right.next move = move.next move.next = left if left else right return head.next
日期: 2021-03-30 Today present at reading group, seems good.