1
0
mirror of https://github.com/SunnyQjm/algorithm-review.git synced 2026-06-03 08:16:43 +08:00
Files
algorithm-review/chapter6/2_sort-list.py
T
2020-06-27 09:07:35 +08:00

86 lines
2.4 KiB
Python

#!/usr/bin/env python
# coding=utf-8
#######################################################################################
# Leetcode 148 排序链表
#
# 在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
#
# 示例 1:
# 输入: 4->2->1->3
# 输出: 1->2->3->4
#
# 示例 2:
# 输入: -1->5->3->4->0
# 输出: -1->0->3->4->5
#######################################################################################
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
def __repr__(self):
if self:
return "{}->{}".format(self.val, repr(self.next))
class Solution:
def sortList(self, head):
"""
:type head: ListNode
:rtype ListNode
(knowledge)
思路:
1. 使用递归方式实现链表的归并排序算法;
2. 对链表进行分治的时候,可以使用快慢指针(快指针一次走两步,慢指针一次走一步,同时从head出发,当快指针走到链表尾的时候,慢指针就走到中间位置);
"""
# 链表为空或者只有一个元素,直接返回
if not head or not head.next:
return head
# low -> 右子链的头部
# pre -> 左子链最后一个节点(未断开之前,指向low)
low, fast, pre = head, head, None
while fast and fast.next:
low, fast, pre = low.next, fast.next.next, low
# 断开左右子链之间的链接
pre.next = None
# 对左右子链分别递归的进行归并排序
head = self.sortList(head)
low = self.sortList(low)
# 对排好序的两部分进行归并
if not low:
return head
result, cur = self, None
while head and low:
if head.val <= low.val:
result.next, head = head, head.next
else:
result.next, low = low, low.next
result = result.next
if not head:
result.next = low
elif not low:
result.next = head
else:
result.next = None
return self.next
if __name__ == '__main__':
solution = Solution()
h1 = ListNode(4)
h1.next = ListNode(2)
h1.next.next = ListNode(1)
h1.next.next.next = ListNode(3)
print(solution.sortList(h1), "= 1->2->3->4")