持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第11天,点击查看活动详情
一 描述
给定单个链表的头 head ,使用 插入排序 对链表进行排序,并返回 排序后链表的头 。
插入排序 算法的步骤:
- 插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
- 每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。
- 重复直到所有输入数据插入完为止。
下面是插入排序算法的一个图形示例。部分排序的列表(黑色)最初只包含列表中的第一个元素。每次迭代时,从输入数据中删除一个元素(红色),并就地插入已排序的列表中。
对链表进行插入排序。
示例 1:
输入: head = [4,2,1,3]
输出: [1,2,3,4]
示例 2:
输入: head = [-1,5,3,4,0]
输出: [-1,0,3,4,5]
提示:
- 列表中的节点数在 [1, 5000]范围内
- -5000 <= Node.val <= 5000
二 分析
如果满足了升序的要求,那么last往前走,cur也往前走
如果不满足,就要把cur的值和链表的头进行比较大小,然后确定一个可以插入的位置,再让cur去插队相当于。
pre在里面就是起到一个占位置的作用,让cur插到它的后面,last相当于是为了cur走了链接到cur的后面,为了下一个cur做准备。
三 答案
# 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: ListNode) -> ListNode:
if not head:
return head
first = ListNode(0) #记录头节点前的节点 以防头节点变化,最后便于输出链表
first.next = head #表明first和头节点的关系
last = head
cur = head.next
while cur:
if cur.val >= last.val:
last = last.next #如果cur大于last 说明不用进行变化,那么last和cur各往前走一步
else:#需要进行变化
pre = first
while cur.val >= pre.next.val: #当pre.next的值比cur的值要小,pre的位置就往前走一步
pre = pre.next
#把cur拎出来插到pre给它占的位置后面,那么last直接跳过cur连接到下一节点
last.next = cur.next
cur.next = pre.next
pre.next = cur
cur = last.next #之前的cur已经完成,又要回到last.next帮它占的位置,往前走了
return first.next