148.排序链表(java)

2023-11-20

148.排序链表

题目描述

O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

示例 1:

输入: 4->2->1->3
输出: 1->2->3->4

示例 2:

输入: -1->5->3->4->0
输出: -1->0->3->4->5

解法一:归并排序

1.递归法(空间复杂度O(n))
  1. 分割环节:用快慢指针找中间节点,分割为左右部分,重复操作
  2. 合并环节:逐个排序,当有一条链为空,将剩下一条加到末尾。返回结果

class Solution {
    public ListNode sortList(ListNode head) {
        return mergeSort(head);
    }
    //分割环节
    public ListNode mergeSort(ListNode head){
        //没有节点或只有1个节点,不用排序
        if(head==null||head.next==null) return head;
        //fast=head会出现栈溢出
        ListNode slow = head,fast = head.next.next,l,r;
        //快慢指针分割找中点
        while(fast!=null&&fast.next!=null){
            slow=slow.next;
            fast=fast.next.next;
        }
        //分割右边
        r = mergeSort(slow.next);
        //断开中间连接
        slow.next=null;
        //分割左边
        l = mergeSort(head);
        return mergeList(head,l,r);
    }
    //合并环节
    public ListNode mergeList(ListNode head,ListNode l,ListNode r){
        ListNode p =new ListNode(0);
        ListNode node =p;
        while(l!=null&&r!=null){
            if(l.val<r.val){
                p.next=l;
                l=l.next;
            }
            else{
                p.next = r;
                r = r.next;
            }
            p=p.next;
        }
        p.next=l==null?r:l;
        return node.next;
    }
}

2.Bottom-to-up

  1. 获取链表长度,创建哨兵结点
  2. 循环n次,根据步长分割链表并两两合并。
  3. 重复步骤2 logn次

class Solution {
    public ListNode sortList(ListNode head) {
        if(head==null||head.next==null) return head;
        //哨兵
        ListNode headnote = new ListNode(0);
        headnote.next=head;
        //链表长度
        int len = countList(head);
        //遍历logn次,从起点开始
        for(int i=1;i<len;i<<=1){
            //两条链,pre连接合并的结点,cur用于分割结点
            ListNode pre = headnote;
            ListNode cur = headnote.next;
            //遍历n次
            while(cur!=null){
                //取cur链起点
                ListNode left = cur;
                //分割两个片段,并合并,放在起点后面
                ListNode right = spilt(left,i);
                cur = spilt(right,i);
                pre.next = mergeList(left,right);
                //更新pre链的终点
                while(pre.next!=null) {
                    pre=pre.next;
                }
            }
        }
        return headnote.next;
    }
    //根据步长拆分结点
    public ListNode spilt(ListNode head,int step){
        if(head==null) return null;
        for(int i=1;i<step&&head.next!=null;i++){
            head=head.next;
        }
        //取还没分割链的起点
        ListNode right=head.next;
        //断开链表
        head.next=null;
        return right;
    }
    //计算链表长度
    public int countList(ListNode head){
        ListNode cur = head;
        int count =0;
        while(cur!=null){
            count++;
            cur=cur.next;
        }
        return count;
    }
    //合并链表
    public ListNode mergeList(ListNode l,ListNode r){
        ListNode p =new ListNode(0);
        ListNode node =p;
        while(l!=null&&r!=null){
            if(l.val<r.val){
                p.next=l;
                l=l.next;
            }
            else{
                p.next = r;
                r = r.next;
            }
            p=p.next;
        }
        p.next=l==null?r:l;
        return node.next;
    }
}


解法二:快排(空间复杂度O(n))

  1. 需要创建一个头头节点,用于连接临时链表
  2. 将小于划分点的结点放到临时链表
  3. 原链表接在临时链表后面,头节点后面接临时链表
class Solution {
    public ListNode sortList(ListNode head) {
        if(head==null||head.next==null)  return head;
        ListNode headnode = new ListNode(0);
        headnode.next = head;
        return quickSort(headnode,null);
    }
    public ListNode quickSort(ListNode head,ListNode end){
        //终止条件,只有1个数,不用排
        if(head==end||head.next==end||head.next.next==end) return head;
        //临时链表,将小于划分点值存入
        ListNode tmpLink = new ListNode(0);
        //partition为划分点,p为链表指针,tmp为临时链表指针
        ListNode partition = head.next,p = partition,tmp = tmpLink;
        //将小于划分点的结点放入临时链表
        while (p.next!=end){
            if (p.next.val<partition.val){
                tmp.next=p.next;
                tmp=tmp.next;
                p.next=p.next.next;
            }else {
                p=p.next;
            }
        }
        //原链表放在临时链表后面
        //用tmp而不是tmpLink
        tmp.next=partition;
        //临时链表插回头结点
        head.next=tmpLink.next;
        quickSort(head,partition);
        quickSort(partition,end);
        return head.next;
    }
}

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

148.排序链表(java) 的相关文章

  • Android 中的 java.util.Observable 是线程安全的吗?

    Android 中的 java util Observable 是线程安全的吗 这文档 http developer android com reference java util Observable html说只有deleteObser
  • 如何抑制 Cucumber/Junit 断言堆栈跟踪

    我有一个黄瓜场景 该步骤使用assertEquals 我的结果报告显示了对最终用户不友好的堆栈跟踪 我怎样才能抑制它 Scenario Add two numbers Given I have two inputs 3 and 2 When
  • Java - 红、绿、蓝获取RGB

    通过致电getRGB int x int y with a BufferedImage对象 得到一个负数 如何将三个不同的值 红色 绿色和蓝色 转换为这个单个负数 使用颜色类 new Color r g b getRGB
  • 在此代码中,Runnable 未实例化。为什么?

    Runnable cannot instantiate public class Thread4 public static void main String args Thread t1 new Thread new Runnable R
  • Android CursorAdapter、ListView 和后台线程

    我一直在开发的这个应用程序有包含数兆字节数据的数据库可供筛选 许多活动只是列表视图 通过数据库中的各个级别的数据下降 直到到达 文档 即从数据库中提取并显示在手机上的 HTML 我遇到的问题是 其中一些活动需要能够通过捕获击键并重新运行带有
  • APNS(Apple 推送通知服务器)的反馈服务

    我们正在使用Java作为推送通知提供商APNS I我能够将消息发送到APNS但我不知道如何获得该消息的反馈 请帮忙 反馈服务具有类似于用于发送推送通知的接口的二进制接口 您可以通过以下方式访问生产反馈服务feedback push appl
  • Spring @Validated 在服务层

    Hej 我想使用 Validated group Foo class 在执行方法之前验证参数的注释 如下所示 public void doFoo Foo Validated groups Foo class foo 当我将此方法放入 Spr
  • 探索java图像处理的好资源[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我是图像处理领域的新手 请推荐一些好的资源 书籍和网络链接 来学习 Java 中的图像处理 最适合隐写术分析 适合初学者和高级水平 我看过
  • 为什么我的 @OneToMany 属性出现主键违规?

    我有一个实体 Entity public class Student GeneratedValue strategy GenerationType AUTO Id private long id OneToMany private Set
  • Java - toString 到 Color

    我一整天都在努力解决这个问题 基本上我做了一个 for 循环 将条目添加到数组列表中 其中一项是 颜色 变量 我已经用过random nextInt为颜色构造函数的红色 绿色和蓝色部分创建新值 我还设置了一个toString方法 这样我就可
  • 如何使用 Swipe 视图实现 Android TabLayout 设计支持库

    我将使用 android TabLayout 设计支持库 但我不知道如何使用滑动视图 这是我的代码 XML
  • java 中的 Try-with-resources 和 return 语句

    我想知道是否放一个return里面的声明尝试资源block 防止资源自动关闭 try Connection conn return conn createStatement execute 如果我写这样的东西将会联系被关闭 Oracle 文
  • Java:不使用 Arrays.sort() 对整数数组进行排序

    这是我们 Java 课程的练习之一中的说明 首先 我想说我 做了我的功课 我不仅仅是懒惰地请 Stack Overflow 上的人帮我回答这个问题 在所有其他练习中 这个特定项目一直是我的问题 因为我一直在努力寻找 完美的算法 编写JAVA
  • EJB 中 @Stateless 相对于 @Singleton 的真正用例是什么

    如果我正确理解EJB Singleton实际上与普通Java中的Singleton相同 也是spring中的单例 gt 一个实例 每个调用同时通过同一个实例 Stateless 声明一个 bean 它可以 但不得 具有多个实例 但限制是一个
  • java中的第三个布尔状态是什么?

    虽然我知道根据定义 布尔值仅包含两种状态 真或假 我想知道布尔值在用这些状态之一初始化之前有什么值 它默认为 false http java sun com docs books tutorial java nutsandbolts dat
  • 从特定 JAR 文件读取资源(文件的重复路径)

    假设您有 jar1 和artifactId 动物园 jar2 和artifactId 动物 两个 jar 都有一个具有相同路径的资源文件 例如 animals animal txt 有什么方法可以从特定的 jar 中读取该文件吗 使用 ge
  • 动态创建 JSON 对象

    我正在尝试使用以下格式创建 JSON 对象 tableID 1 price 53 payment cash quantity 3 products ID 1 quantity 1 ID 3 quantity 2 我知道如何使用 JSONOb
  • Javac 版本 1.7 无法为目标 1.7 构建

    我试图在 Linux Mint 系统上使用 Sun Java JDK 1 7 0 17 编译 Java 代码 但遇到了这个问题 javac version target 1 7 javac 1 7 0 17 javac invalid ta
  • 一个类中有多个具有相同参数类型的方法

    我知道 至少已经有了关于这个主题的一个问题 https stackoverflow com questions 5561436 can two java methods have same name with different retur
  • 通过向上转换将 Java.sql.date 转换为 Java.util.date 安全吗?

    java sql date 扩展了 java util date 那么通过将 java sql date 转换为 java util date 是否可以在两者之间进行转换 或者有其他方法可以转换它们吗 您不一定需要强制转换 您可以将 SQL

随机推荐

  • glog的编译,配置,使用

    glog是Google推出的轻量级C log开源库 使用起来比较简单 自己可以下载源码直接编译 支持Windows和linux 下载编译 glog下载路径 https code google com p google glog 需要翻墙才能
  • js 根据总页数 和 规律的页面名称 动态创建分页条

    公有变量最好用明明空间限制一下 var totalPage 0 var currentPage 1 var menuType 0 var totalCount 0 var first page 首页 var prev page 上一页 va
  • mybatis实现代码自动生成

    1 在pom文件中加入代码自动生成插件
  • 光圈,焦距,工作距离与景深之间的关系。

    光圈 光圈越大 景深越小 光圈越小 景深越大 焦距 焦距越长 景深越小 焦距越短 景深越短 工作距离 工作距离越小 景深越小 工作距离越大 景深越大
  • linux和shell的关系

    shell的理解 shell翻译成壳的意思 它是包裹在linux内核外层的 一个可通过一系列的linux命令对操作系统发出相关指令的人机界面 shell可以通过其条件语句和循环语句等 把一系列linux命令结合在一起 形成一个相当于面向过程
  • Java——面向对象练习(图书管理系统的实现)

    文章目录 Java 面向对象练习 图书管理系统的实现 一 实现效果展示 1 功能简介 2 登陆界面 3 菜单界面 4 功能展示 二 具体代码实现 1 类的设计 1 创建图书相关的类 2 创建操作相关的类 1 接口的实现 2 新增书籍 3 删
  • 谷歌(Chrome)浏览器自定义插件

    准备 1 js文件 需要的功能逻辑 2 插件主入口及配置 manifest json 3 插件图标 目录结构 添加插件流程 选择插件文件夹 代码 manifest json name 百度 manifest version 2 versio
  • C语言基础-----(8)控制语句

    6 控制语句 6 1 顺序语句 c语言从主函数当中的第一条语句开始执行 6 2 选择语句 6 2 1单分支 if 表达式 语句块1 else 语句块2 step 判断表达表达式 如果表达式为真 则执行语句块1 如果表达式为假 则执行语句块2
  • mysql一键更改图片地址_利用mysql语句批量替换指定wordpress文章图片路径

    有时候当你看到一篇十分优秀的国外文章的时候 比如说十个优秀 五十个优秀的网站设计欣赏 wordpress主题下载 jquery插件下载等等 这些文章当中往往会跟随大量的示例图片供读者查看 如果这些文章很有收藏价值 你可能会直接进行翻译或转载
  • 机器学习---监督学习、无监督学习

    机器学习 什么是机器学习 两种主要类型是 监督学习和无监督学习 强化学习 监督学习 什么是监督学习 回归问题 预测连续值输出 eg 预测房价 分类问题 预测离散值输出 eg 预测肿瘤 监督学习 给算法一个数据集 其中包含了正确答案 输入x
  • Android项目中三种依赖的添加方式

    添加本地依赖 首先将所需的 jar 或者 aar 包放在libs文件夹下 方式1 右击jar包 选择Add As Library 最后sync 方式2 在app build gradle中添加本地依赖的声明 implementation f
  • MCU 常用的文件系统

    片外FLASH SPIFFS FATFS LittleFs 片上FLASH FlashDB EasyFlash
  • python3爬虫伪装代理IP

    在爬取类似 起点 色魔张大妈 这样的网站时 会被网站看出是爬虫机制 这时需要伪装成浏览器以及使用IP代理的方式来爬去正常内容 实例 import re import requests import urllib request from l
  • shopify上传主题

    shopify theme 多语言国际化开发 shopify theme 跨境电商开发 liquid 本地编辑shopify主题的方式一 shopify cli 的命令
  • 从《模仿游戏》认识图灵

    模仿游戏 剧情简介 模仿游戏这部电影主要讲述了在二战期间 英国为了破解德军的加密系统Enigma密码机招募了一批有才华的破译者来执行此项国家最高机密任务 艾伦 图灵就是其中之一 然而图灵孤僻的性格让他与别的同事不能融洽相处 图灵一意孤行要建
  • 计算机怎么解除c盘用户权限,电脑c盘文件夹拒绝访问怎么办 删除c盘文件如何获得管理员权限...

    c盘是我们系统文件存储的关键位置 当我们想要查看c盘的时候 出现拒绝访问的情况怎么解决呢 其实很简单 下面小编为大家带来打开c盘文件夹拒绝访问的详细解决方法 大家可以直接按照下面的步骤即可解决 电脑c盘文件夹拒绝访问怎么办 1 通常情况下
  • JVM监控工具和方法

    在JVM运行的过程中 为保证其稳定 高效 或在出现GC问题时分析问题原因 我们需要对GC进行监控 所谓监控 其实就是分析清楚当前GC的情况 其目的是鉴别JVM是否在高效的进行垃圾回收 以及有没有必要进行调优 通过监控GC 我们可以搞清楚很多
  • 代码点(code point)和代码单元(code units)

    1 解释一 char Java中 char类型为16个二进制位 原本用于表示一个字符 但后来发现 16位已经不够表示所有的字符 所以后来发展出了代码点表示字符的方法 代码点 code point 是指编码字符集中 字符所对应的数字 有效范围
  • 题目94:时间函数,一个猜数游戏,判断一个人反应快慢。

    import time import random play input 请问你想玩1 100猜字游戏吗 yes no n while play yes number random randint 1 100 guess int input
  • 148.排序链表(java)

    148 排序链表 题目描述 在 O n log n 时间复杂度和常数级空间复杂度下 对链表进行排序 示例 1 输入 4 gt 2 gt 1 gt 3 输出 1 gt 2 gt 3 gt 4 示例 2 输入 1 gt 5 gt 3 gt 4