Sort List

2023-11-18

Sort a linked list in O(n log n) time using constant space complexity.

题目要求用 O(n log n)的时间复杂度和常数的空间复杂度来进行链表排序。

O(nlogn)的排序算法有堆排,快排,归并排序等,一开始我准备采用快排,后来发现每次需要交换元素的时候的十分痛苦。而实用归并排序,其实本身就是调用

Merge Two Sorted Lists。所以还是使用归并来得简单一些。进行链表排序和数组排序的不同点在于需要维护一个前序结点,维持链表的连续性。另外这里不能使用index来直接获得左右子链表,需要做一次遍历来割取左右子链表。一个办法是使用slow和fast两个指针,fast每次走两步,slow每次走一步,fast到达尾部时,slow就到达了链表中部。这样实现的代码如下:

class Solution(object):
    def sortList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if not head or not head.next :
            return head
        dummy = ListNode(-1)
        dummy.next = head   #防止头结点需要换位,先建立一个辅助的先序结点
        slow = fast = dummy #一慢一快两个指针
#分割左右两个子链表
while fast and fast.next: slow = slow.next fast = fast.next.next tmp = slow.next #注意为了合并左右子链表,需要将第一个子链表尾结点的next置为None。 slow.next = None slow = tmp left = self.sortList(head) #递归排序左子链表 right = self.sortList(slow) #递归排序右子链表 cur = dummy
#merge操作
while left and right: if left.val < right.val: cur.next = left left = left.next else: cur.next = right right = right.next cur = cur.next cur.next = left if left else right return dummy.next

上述的解法需要递归的,空间复杂度为O(nlogn),所以其实不符合题目要求的常数空间复杂度的要求。时间上每次进行左右分割的时间和merge的时间复杂度都是O(n)。总体的时间复杂度还是O(nlogn)。

对上述的代码去递归,采用迭代处理。思路时先进行相邻2个结点的排序,之后进行4个,然后8个,这种自底向上的思路在CUDA高性能计算上也有应用。思路很熟悉。主要时维护一个step,开始为1,然后为2,之后是4,示意如下:

Round #1 block_size = 1

(a1, a2), (a3, a4), (a5, a6), (a7, a8)

Compare a1 with a2, a3 with a4 ...

Round #2 block_size = 2

(a1, a2, a3, a4), (a5, a6, a7, a8)

merge two sorted arrays (a1, a2) and (a3, a4), then merge tow sorted arrays(a5, a6) and (a7, a8)

Round #3 block_size = 4

(a1, a2, a3, a4, a5, a6, a7, a8)

实现的代码如下:

class Solution(object):
    def sortList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if not head or not head.next:
            return head
        dummy = ListNode(-1)
        dummy.next = head
        length = 0
        cur = head
        while(cur):  #get the length
            length += 1
            cur = cur.next
        step = 1
        while step < length: #the main part of sorting, from short length to long length 
            cur = dummy.next
            tail = dummy
            while cur:
                l = cur
                r = self.split(l, step)
                cur = self.split(r, step)
                tail = self.merge(l, r, tail)
            step <<= 1
        return dummy.next
    #分割要排序的块,返回该块尾结点的后一个结点。        
    def split(self,start, step):
        if not start:
            return None
        for i in xrange(step-1):
            if start:
               start = start.next
            else:
               return None
        if not start:
            return None
        end = start.next
        start.next = None
        return end
    #合并两个链表,注意要返回排序后的链表的尾结点,方便后序的连接         
    def merge(self,l, r, head):
        if not r:
            head.next = l
        cur = head
        while l and r:
            if l.val < r.val:
                cur.next = l
                l = l.next
            else:
                cur.next = r
                r = r.next
            cur = cur.next
        cur.next = l if l else r
        while cur.next: #找寻尾结点
            cur = cur.next
        return cur

上述思路不难,但是和所有的链表题一样,需要考虑找这个结点,还是前序还是后序,如何建立连接,如何防止越界。考虑的corner case比较多。

转载于:https://www.cnblogs.com/sherylwang/p/5542685.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Sort List 的相关文章

  • 如何覆盖 Django 的默认管理模板和布局

    我正在尝试覆盖 Django 的默认模板 现在只有base site html 我正在尝试更改 django 管理文本 我做了以下事情 我在我的应用程序目录中创建了一个文件夹 opt mydjangoapp templates admin
  • 将 transaction.commit_manually() 升级到 Django > 1.6

    我继承了为 Django 1 4 编写的应用程序的一些代码 我们需要更新代码库以使用 Django 1 7 并最终更新到 1 8 作为下一个长期支持版本 在一些地方它使用旧风格 transaction commit manually and
  • 使用 Python 创建 MIDI

    本质上 我正在尝试从头开始创建 MIDI 并将它们放到网上 我对不同的语言持开放态度 但更喜欢使用Python 两种语言之一 如果这有什么区别的话 并且想知道我应该使用哪个库 提前致谢 看起来这就是您正在寻找的 适用于 Python 的简单
  • 如何使用 colorchecker 在 opencv 中进行颜色校准?

    我有数码相机获取的色彩检查器图像 我如何使用它来使用 opencv 校准图像 按照以下颜色检查器图像操作 您是想问如何进行颜色校准或如何使用 OpenCV 进行校准 为了进行颜色校准 您可以使用校准板的最后一行 灰色调 以下是您应该逐步进行
  • NumPy linalg.eig

    我有这个烦人的问题 但我还没有弄清楚 我有一个矩阵 我想找到特征向量 所以我写 val vec np linalg eig mymatrix 然后我得到了 vec 我的问题是 当我小组中的其他人对相同的矩阵 mymatrix 做同样的事情时
  • 在Python中如何获取字典的部分视图?

    是否有可能获得部分视图dict在Python中类似于pandasdf tail df head 说你有很长一段时间dict 而您只想检查某些元素 开头 结尾等 dict 就像是 dict head 3 To see the first 3
  • cv2.drawContours() - 取消填充字符内的圆圈(Python,OpenCV)

    根据 Silencer的建议 我使用了他发布的代码here https stackoverflow com questions 48244328 copy shape to blank canvas opencv python 482465
  • Python 是解释型的还是编译型的,或者两者兼而有之?

    据我了解 An 解释的语言是由解释器 将高级语言转换为机器代码然后执行的程序 实时运行和执行的高级语言 它一次处理一点程序 A compiled语言是一种高级语言 其代码首先由编译器 将高级语言转换为机器代码的程序 转换为机器代码 然后由执
  • 字符串中的注释和注释中的字符串

    我正在尝试使用 Python 和 Regex 计算 C 代码中包含的注释中的字符数 但没有成功 我可以先删除字符串以删除字符串中的注释 但这也会删除注释中的字符串 结果会很糟糕 是否有机会通过使用正则表达式来询问不匹配注释中的字符串 反之亦
  • 使用 NLTK 在 Python 中获取大量名词(或形容词);或 Python Mad Libs

    Like 这个问题 https stackoverflow com questions 7439555 noun adjective etc word lists or dictionaries common words 我有兴趣按词性获取
  • 如何在VIM中设置文件的正确路径?

    每当我击中 pwd在 vim 中命令总是返回路径C Windows system32 即使我在桌面上的 Python 文件中 所以每当我跑步时 python 命令返回 python can t open file Users myname
  • 如何在Python中高效地添加稀疏矩阵

    我想知道如何在Python中有效地添加稀疏矩阵 我有一个程序 可以将大任务分解为子任务 并将它们分配到多个 CPU 上 每个子任务都会产生一个结果 一个 scipy 稀疏矩阵 格式为 lil matrix 稀疏矩阵尺寸为 100000x50
  • 将 numpy 代码点数组与字符串相互转换

    我有一个很长的 unicode 字符串 alphabet range 0x0FFF mystr join chr random choice alphabet for in range 100 mystr re sub W mystr 我想
  • 对使用 importlib.util 导入的对象进行酸洗

    我在使用Python的pickle时遇到了一个问题 我需要通过将文件路径提供给 importlib util 来加载一些 Python 模块 如下所示 import importlib util spec importlib util sp
  • Python、subprocess、call()、check_call 和 returncode 来查找命令是否存在

    我已经弄清楚如何使用 call 让我的 python 脚本运行命令 import subprocess mycommandline lumberjack sleep all night work all day subprocess cal
  • Python:我不明白 sum() 的完整用法

    当然 我明白你使用 sum 与几个数字 然后它总结所有 但我正在查看它的文档 我发现了这一点 sum iterable start 第二个参数 start 的作用是什么 这太尴尬了 但我似乎无法通过谷歌找到任何示例 并且对于尝试学习该语言的
  • 为什么我应该使用 WSGI?

    使用 mod python 一段时间了 我读了越来越多关于 WSGI 有多好的文章 但没有真正理解为什么 那么我为什么要切换到它呢 有什么好处 这很难吗 学习曲线值得吗 为了用 Python 开发复杂的 Web 应用程序 您可能会使用更全面
  • 操作错误:(sqlite3.OperationalError) SQL 变量太多,同时将 SQL 与数据帧一起使用

    我有一个熊猫数据框 如下所示 activity User Id 0 VIEWED MOVIE 158d292ec18a49 1 VIEWED MOVIE 158d292ec18a49 2 VIEWED MOVIE 158d292ec18a4
  • 使用 Python 将对象列表转为 JSON

    我在转换时遇到问题Object实例到 JSON ob Object list name scaping myObj base url u number page for ob in list name json string json du
  • python 中的 after() 与 update()

    我是 python 新手 开始使用 tkinter 作为画布 到目前为止 我使用 update 来更新我的画布 但还有一个 after 方法 谁能给我解释一下这个函数 请举个例子 两者之间有什么区别 root after integer c

随机推荐

  • MES的数据采集方式

    为实现生产车间现场数据的采集 制造业MES系统数据采集方法有手工录入方式和自动化提取采集两大类 主要有以下几类 一 手动方式 1 手工方式 操作员或编程员在MES系统控制面板上 输入特定的触发程序 经DNC服务器的自动翻译 就可得到机床端的
  • Jenkins集成Sonar与Gitlab代码质量检测

    前提默认 安装docker19 与docker compose 安装Jenkins 1 docker compose yaml配置 version 3 services jenkins network mode host 镜像 image
  • 3、Java的If语句与For循环

    一 语句 条件语句 根据不同的条件 执行不同的语句 if if else if else if if else if else if else switch 循环语句 重复执行某些动作 for while do while 1 1 if语句
  • 深度学习算法面试常问问题(三)

    pooling层是如何进行反向传播的 average pooling 在前向传播中 就是把一个patch的值取平均传递给下一层的一个像素 因此 在反向传播中 就是把某个像素的值平均分成n份 分配给上一层 max pooling 在前向传播中
  • 用Odoo创建一个网站

    原贴地址 https www odoo com documentation 10 0 howtos website html 声明 这篇指导假设你有python的知识并安装了Odoo 请注意文件的目录结构 本文的目录结构与原文不同 创建一个
  • 快速打开CMD的几个方法

    1 在开始菜单里面找CMD EXE 很快的哟 2 在资源管理器的地址栏直接键入CMD按回车也能启动CMD 3 资源管理器 按住Shift点右键也能召唤CMD哦 选 在此处打开命令窗口 就行了
  • squirrel-foundation状态机的使用细节

    上一篇文章介绍了stateless4j spring statemachine以及squirrel foundation三款状态机引擎的实现原理 以及我为何选择squirrel foundation作为解决方案 本文主要介绍一下项目中如何使
  • sqlloader出现SQL*Loader-704和ORA-12154的错误

    1 错误描述 生成的sqlloder各个文件完好 权限也具备 但是就是导入oracle数据库的时候报错 错误为 SQL Loader 704 Internal error ulconnect OCIServerAttach 0 ORA 12
  • vue3+ts实现todolist功能

    先看一下实现效果 可以看到内部实现的内容有enter输入 单项删除 全选 以及删除选中项等功能 具体在实现前需要常见有ts的vue3项目 项目创建 具体项目创建 就是 vue create 项目名称 在创建后 选择的时候有vue2和vue3
  • CUDA10.0官方文档的翻译与学习之介绍

    背景 从这次开始 我将用数篇博客来分享前一阵我对CUDA10 0官方文档之编程指南的翻译与学习的笔记 由于内容非常多 我将每一章单独分享出来 可能有地方翻译得词不达意 所以建议大家参考原文 https docs nvidia com cud
  • 多线程实现事务回滚

    多线程实现事务回滚 特别说明CountDownLatch CountDownLatch的用法 CountDownLatch num 简单说明 主线程 mainThreadLatch await 和mainThreadLatch countD
  • 剑指 offer第62题-圆圈中最后剩下的数

    让小朋友们围成一个大圈 然后 随机指定一个数 m 让编号为 0 的小朋友开始报数 每次喊到 m 1 的那个小朋友要出列唱首歌 然后可以在礼品箱中任意的挑选礼物 并且不再回到圈中 从他的下一个小朋友开始 继续 0 m 1 报数 这样下去 直到
  • Proc批量处理需要注意的问题

    ProC中批量读取游标中的数据的时候 需要注意 最后一次批量读取游标中的数据的时候 数据被取到HostArray中 同时sqlca sqlcode被置为1403 NO DATA FOUND 如果在fetch后立即判断sqlca sqlcod
  • 隐藏selenium的特征

    1 chromedriver exe中的 cdc asdjflasutopfhvcZLmcfl 特征 cdc 是chromedriver exe的一个特征之一 很多网站会通过检测是否有这个特征来判断是否是selenium 解决方案 wind
  • centos7安装mate

    http www 45drives com wiki index php Installing MATE on CentOS 7 Note This guide assumes you have a CentOS 7 minimal ins
  • Python基础知识之5

    Python基础知识之5 文件操作 1 文件的打开与关闭 文件打开 在python 使用open函数 可以打开一个已经存在的文件 或者创建一个新文件 基本格式 open 文件名 访问模式 实例如下 f open test txt w 文件关
  • 关于soot静态分析的学习(一)

    本文中关于soot的研究使用 仅代表本人理解程度 因本人为0基础 所以如有出错 欢迎指出 一 soot是什么 Soot Java静态分析框架 其实Soot最开始设计的时候 主要目的就是为了对Java字节码程序进行优化 这里的优化就是指执行效
  • 【Qt】Qt事件系统

    00 目录 文章目录 00 目录 01 Qt事件系统概述 02 事件如何传递 03 事件类型 04 事件处理 05 事件过滤器 06 事件发送 附录 01 Qt事件系统概述 Qt 5 12 Qt Core The Event System
  • vb和asp如何用remote访问远程数据库

    访问远程数据库的情况有以下几种 1 访问远程数据库的access数据库2 访问远程mssql数据库或oracle等其他关系数据库 但是数据库通信端口被防火墙阻挡或其他网络原因造成无法使用该端口 本文仅在windows2000 advance
  • Sort List

    Sort a linked list in O n log n time using constant space complexity 题目要求用 O n log n 的时间复杂度和常数的空间复杂度来进行链表排序 O nlogn 的排序算