• 打败算法 —— 排序链表


    本文参考

    出自LeetCode上的题库 —— 排序链表

    https://leetcode-cn.com/problems/sort-list/

    排序问题

    给定链表的头结点 head ,按升序排列并返回排序后的链表

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

    示例 2:
    输入:head = [-1,5,3,4,0]
    输出:[-1,0,3,4,5]

    示例 3:
    输入:head = []
    输出:[]

    解题思路

    题干非常容易理解,就是对单向链表进行排序,和数组不同的是,我们不能在排序过程中随机访问链表中的每一个元素,因此无法应用需要向左遍历的排序方法,如快速排序。和快速排序具有相同时间复杂度$O(nlogn)$的归并排序是个不错的选择,我们可以先通过快慢指针将常链表分为前后两个部分,然后递归调用排序函数,是十分容易理解的分治思想。最后的merge函数也同常规的归并算法类似。

    归并排序解法

    class ListNode:
      def __init__(self, val=0, next=None):
        self.val = val
        self.next: ListNode = next


    class Solution:
      def sort_list(self, head: Optional[ListNode]) -> Optional[ListNode]:
        # 空链表或仅有一个结点的链表 

        if head is None or head.next is None:
          return head

        # 仅有两个结点的链表 

        if head.next.next is None:
          if head.val > head.next.val:
            head.val, head.next.val = head.next.val, head.val
          return head

        # 利用快慢指针将链表分为两个部分 

        slow = fast = head
        while fast.next and fast.next.next:
          slow = slow.next
          fast = fast.next.next

        front = head
        back = slow.next
        slow.next = None

        # 分治 

        front = self.sort_list(front)
        back = self.sort_list(back)

        # 合并 

        return self.merge(front, back)

      def merge(self, front: ListNode, back: ListNode):
        head = ListNode()
        curr = head
        while front and back:
          if front.val <= back.val:
            curr.next = front
            front = front.next
          else:
            curr.next = back
            back = back.next
            curr = curr.next

        if front is None:
          while back:
            curr.next = back
            curr = curr.next
            back = back.next
        else:
          while front:
            curr.next = front
            curr = curr.next
            front = front.next
        return head.next

  • 相关阅读:
    css动画集合地址
    邮箱正则
    好用的工具之一 ---- Sublime Text
    组件化表单解决方案AForm 1.3 发布
    WinScp几个极大提高开发效率的小功能
    session的本质及如何实现共享?
    使用phantomjs操作DOM并对页面进行截图需要注意的几个问题
    Ubuntu 12.04 安装最新版本NodeJS
    IIS 8 nodejs + iisnode 配置
    Bagging和Boosting的介绍及对比
  • 原文地址:https://www.cnblogs.com/kuluo/p/15968619.html
Copyright © 2020-2023  润新知