日新刷题 - 147. 对链表进行插入排序

93 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第11天,点击查看活动详情

一 描述

147. 对链表进行插入排序 - 力扣(LeetCode)

给定单个链表的头 head ,使用 插入排序 对链表进行排序,并返回 排序后链表的头 。

插入排序 算法的步骤:

  1. 插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
  2. 每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。
  3. 重复直到所有输入数据插入完为止。

下面是插入排序算法的一个图形示例。部分排序的列表(黑色)最初只包含列表中的第一个元素。每次迭代时,从输入数据中删除一个元素(红色),并就地插入已排序的列表中。

对链表进行插入排序。

Insertion-sort-example-300px.gif

示例 1:

image.png

输入: head = [4,2,1,3]
输出: [1,2,3,4]

示例 2:

image.png

输入: 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