题目¶
原题地址:https://leetcode.com/problems/insertion-sort-list/
Sort a linked list using insertion sort.
A graphical example of insertion sort. The partial sorted list (black) initially contains only the first element in the list. With each iteration one element (red) is removed from the input data and inserted in-place into the sorted list
Algorithm of Insertion Sort:
- Insertion sort iterates, consuming one input element each repetition, and growing a sorted output list.
- At each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there.
- It repeats until no input elements remain.
Example 1:
Input: 4->2->1->3 Output: 1->2->3->4
Example 2:
Input: -1->5->3->4->0 Output: -1->0->3->4->5
解法¶
生成一个有序数组,然后再生成结果链表¶
简单来说就是,先遍历链表生成一个有序数组,然后再基于这个数组生成所需的链表。
这个方法的 Python 代码类似下面这样:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def insertionSortList(self, head):
nodes = []
while head is not None:
self.insert_node(nodes, head)
head = head.next
dummy = ListNode()
tail = dummy
for node in nodes:
tail.next = node
tail = node
# 防止节点上原有的 next 属性值导致出现循环
tail.next = None
return dummy.next
def insert_node(self, nodes, node):
for i, v in enumerate(nodes):
if node.val < v.val:
nodes.insert(i, node)
break
else:
nodes.append(node)
return nodes
不生成中间数组,直接对链表进行排序操作¶
可以省略中间数组,在对链表进行遍历的过程中按照上面数组类似的逻辑进行排序。
- 定义一个空链表 dummy ,作为排序后的结果链表,类似上面的中间数组
- 遍历输入的链表,将节点插入到上面的 dummy 链表中,为了保持 dummy 有序,需要按上面类似 insert_node 的方法在 dummy 中找到合适的位置,因为 dummy 是个链表而不是数组无法直接插入,需要记录插入位置的上一个节点 (pre_node) 和下一个节点(next_node),然后再基于这两个节点的信息实现插入新节点的功能。
这个方法的 Python 代码类似下面这样:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution(object):
def insertionSortList(self, head):
# 新的链表
dummy = ListNode()
current = head
while current is not None:
# 把 current 插入到 dummy 链表中
# 新节点插入位置的上一个节点
pre_node = dummy
# 新节点插入位置的下一个节点
next_node = pre_node.next
while next_node is not None:
# 找到插入位置
if current.val < next_node.val:
break
pre_node = next_node
next_node = next_node.next
# 插入新节点
pre_node.next = current
_next = current.next
current.next = next_node
current = _next
return dummy.next
Comments