【LeetCode-中等题】148. 排序链表

文章目录

    • 题目
    • 方法一:集合排序(核心是内部的排序)
    • 方法二: 优先队列(核心也是内部的排序)
    • 方法三:归并排序(带递归) 从上往下
    • 方法四:归并排序(省去递归,用迭代) 从下往上

题目

在这里插入图片描述

方法一:集合排序(核心是内部的排序)

把链表放到List集合,排好序,再依据List集合创建一个新有序链表返回就行了

//方法一 集合倒序  (存.val值在转换为ListNode)public ListNode sortList(ListNode head) {if(head == null) return head;List<Integer> list = new ArrayList<>();ListNode node = head;while(node != null){list.add(node.val);node = node.next;}Collections.sort(list);//升序排列ListNode min = new ListNode(list.get(0));//直接找出小值记录头结点node = min;for(int i = 1; i<list.size(); i++){ListNode h = new ListNode(list.get(i));node.next = h;node = node.next;}return min;}// 方法一 集合倒序(存ListNode值直接调用Comparator接口进行值排序)//     public ListNode sortList(ListNode head) {//     if(head == null){//         return null;//     }//     List<ListNode> list  = new ArrayList<>();//     while(head !=null){//         list.add(head);//         head = head.next;//     }//     list.sort(new Comparator<ListNode>(){//         @Override//         public int compare(ListNode o1, ListNode o2) {//             return o1.val - o2.val;//         }//     });//     for(int i = 0 ; i < list.size() - 1;i++){//         list.get(i).next = list.get(i + 1);//     }//     list.get(list.size() - 1).next = null;//     return list.get(0);

方法二: 优先队列(核心也是内部的排序)

优先队列 往这个优先队列中插入元素时,会按照节点 val 属性的大小顺序进行排序,即小的节点排在前面,大的节点排在后面。依次谈栈再创建新链表
优先队列声明

PriorityQueue<ListNode> queue = new PriorityQueue<>((node1, node2) -> node1.val - node2.val);
  	((node1, node2) -> node1.val - node2.val)  升序排列((node1, node2) -> node2.val - node1.val)  降序排列
 public ListNode sortList(ListNode head) {PriorityQueue<ListNode> queue = new PriorityQueue<>((node1, node2) -> node1.val - node2.val);ListNode cur = head;while (cur != null) {queue.offer(cur);cur = cur.next;}ListNode dummy = new ListNode(0);cur = dummy;while (!queue.isEmpty()) {cur.next = queue.poll();cur = cur.next;}cur.next = null;return dummy.next;}

方法三:归并排序(带递归) 从上往下

先找到中间点 按中间点切割链表 然后排序好切割好的两头的链表 再将两个排序好的链表合并起来 (递归终止条件是切割到只有一个节点,直接返回可以排序了)

  1. 先找到待排序链表的中间节点(快慢指针找)
  2. 再根据中间节点对两边的链表分别进行归并排序(递归)
  3. 将排序好的两部分链表进行合并( 双指针法 无需递归)

在这里插入图片描述

         public ListNode sortList(ListNode head) {return mergeSort(head);}// 归并排序private ListNode mergeSort(ListNode head){if(head ==null || head.next==null) return head;// 如果没有结点/只有一个结点,无需排序,直接返回--也是递归的出口// 快慢指针找出中位点ListNode fast = head.next;//让fast比slow快1个位置,这样最后solw会停在链表中间点前一个位置// ListNode fast = head.next.next;//两种方式都可以  最终slow都会停在中间点前一个位置ListNode slow = head;//记住这个判断条件,偶数结点会找靠左结点,奇数就是中间节点,能用到很多题上while(fast !=null && fast.next !=null){slow =slow.next;fast = fast.next.next;}// 对右半部分进行归并排序ListNode right = mergeSort(slow.next);// 对左半部分进行断链操作slow.next =null;// 对左半部分进行归并排序ListNode left = mergeSort(head);//合并两个有序链表return mergeList(left,right);} // 合并链表  双指针法private ListNode mergeList(ListNode l,ListNode r){// 临时头节点ListNode tmpHead=new ListNode(-1);ListNode tem = tmpHead;while( l!=null && r!=null ){  //只循环走到任何一方为null时  后面就不需要再比较了  直接把多的哪一方拼接起来就行if(l.val < r.val){tem.next =l;l = l.next;}else{tem.next =r;r = r.next;}tem = tem.next;}if(l==null) tem.next = r;//只循环走到任何一方为null时  后面就不需要再比较了  直接不为null的哪一方拼接起来就行else tem.next =l;return tmpHead.next;}

方法四:归并排序(省去递归,用迭代) 从下往上

核心就行直接定义排序的最小单位 也就是一个节点的链表(大for循环从intv = 1(子俩表长度) 开始 在intv >= 大链表的长度停止),然后分别对链表长度为1 2 3 4 进行合并排序,然后拼接到一起,就是排序号的链表

在这里插入图片描述

 public ListNode sortList(ListNode head) {if(head == null) return head;int length = 0;//统计链表的长度ListNode node = head;while(node != null){length++;node = node.next;}ListNode preHead = new ListNode(0,head);//创建哑结点  preHead--->headfor(int intv = 1; intv < length ;intv=intv*2){ //每次intv扩大两倍   直到intv 大于等于了链表的长度ListNode prev = preHead;//prev为拼接点(拼接合并好的链表)ListNode cur = preHead.next;while(cur != null){//开始拆分ListNode head1 = cur;//intv为1 时的 第一段链表的头节点for(int i = 1 ; i<intv&&cur.next !=null&& cur != null;i++){//找到intv为1 时的 第一段链表的末尾节点  方便找到第二段的头结点 cur=cur.next;//此时循环结束   cur指向的是第一段链表的尾部 }ListNode head2 = cur.next;//intv为1 时的 第二段链表的头节点cur.next = null;  //端链操作  将两部分链表断开cur = head2;  //更新cur到第二段链表的首节点for(int i = 1 ; i<intv && cur != null  && cur.next != null ; i++){cur=cur.next;//此时 cur指向的是第二段链表的尾部}ListNode next = null;if(cur != null){  //记录第二次进行 比较的  第一段链表的第一个节点next = cur.next;cur.next = null;//对第一次比较的第二个链表进行断链}ListNode merged = mergeList(head1,head2);//对第一次的两个链表进行合并排序prev.next = merged;//将合并好的链表 拼接到prev后面while(prev.next != null){prev = prev.next; //把prev移动到拼接好的链表的尾部,方便下次再拼接合并排序好的链表}cur = next;//将cur更新到下一批次合并排序的第一个俩表的头结点}}return preHead.next;}//        // 合并两个有序链表  双指针法private ListNode mergeList(ListNode l,ListNode r){// 临时头节点ListNode tmpHead= new ListNode(-1);ListNode tem = tmpHead;while( l!=null && r!=null ){  //只循环走到任何一方为null时  后面就不需要再比较了  直接把多的哪一方拼接起来就行if(l.val < r.val){tem.next =l;l = l.next;}else{tem.next =r;r = r.next;}tem = tem.next;}if(l==null) tem.next = r;//只循环走到任何一方为null时  后面就不需要再比较了  直接不为null的哪一方拼接起来就行else tem.next =l;return tmpHead.next;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/61013.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

桌面网络存储迎来新浪潮!龙蜥社区联合龙芯首发优龙桌面网络存储一体机方案

2023 年 8 月 19 日&#xff0c;龙蜥社区合作伙伴单位南京龙众创芯电子科技有限公司(以下简称“龙众创芯“)与龙蜥社区理事单位龙芯中科(武汉)技术有限公司&#xff08;以下简称“龙芯”&#xff09;&#xff0c;联合可道云、上海七朵信息等多家生态伙伴&#xff0c;以及龙芯开…

报错:Cannot read properties of undefined (reading ‘$message‘)

报错 一、问题二、分析三、解决 一、问题 Cannot read properties of undefined (reading ‘$message’) 二、分析 是因为在 main.js 文件中&#xff0c;此时还未有 this&#xff0c;我们可以打印一下&#xff0c;是 null 三、解决 如果想要使用 this.$message(这是一条消息…

Jmeter性能压测 —— 高并发思路

测试场景&#xff1a;模拟双11&#xff0c;百万级的订单量一个物流信息的查询接口。 条件&#xff1a;接口响应时间<150ms以内。10万并发量每秒。 设计性能测试方案 1、生产环境 ①10W/S--并发量&#xff08;架构师/技术负责人提供&#xff09; ②20台机器&#xff08;…

rabbitmq的优先级队列

在我们系统中有一个 订单催付 的场景&#xff0c;我们的客户在天猫下的订单 , 淘宝会及时将订单推送给我们&#xff0c;如果在用户设定的时间内未付款那么就会给用户推送一条短信提醒&#xff0c;很简单的一个功能对吧&#xff0c;但是&#xff0c;tianmao商家对我们来说&#…

【力扣 第 360 场周赛】题解(一题待补)

目录 2833. 距离原点最远的点2834. 找出美丽数组的最小和2835. 使子序列的和等于目标的最少操作次数TODO 2836. 在传球游戏中最大化函数值 这场比赛排名第 1 - 1000 名的参赛者 可获「NIO 蔚来」简历内推机会&#xff0c;比有的场次前十才给容易多了。 2833. 距离原点最远的点…

Acwing792. 高精度减法

Acwing792. 高精度减法 题目描述代码展示 题目描述 代码展示 #include <iostream> #include <vector>using namespace std;bool cmp(vector<int> &A, vector<int> &B) {if (A.size() ! B.size()) return A.size() > B.size();for (int i …

利用条件竞争突破优惠券仅能使用一次逻辑限制

Portswigger练兵场之条件竞争 目录 Portswigger练兵场之条件竞争&#x1f984;条件竞争-突破一次逻辑限制&#x1f680;实验前置必要知识点&#x1f3c6;实验要求⚡️渗透开始1. 站点分析2. 登录3.日志探查4.功能点探究5.完成实验 修复方案 &#x1f984;条件竞争-突破一次逻辑…

基于Vue前端框架构建BI应用程序

一、什么是Vue&#xff1f; Vue&#xff08;Vue.js&#xff09;是一个轻量级、高性能、可组件化的MVVM库。简而言之&#xff0c;是一个构建数据驱动的web界面的渐进式框架。它采用MVVM思想&#xff0c;通过数据双向绑定实现数据的动态渲染&#xff0c;同时也支持组件化的开发方…

深度学习论文分享(八)Learning Event-Driven Video Deblurring and Interpolation

深度学习论文分享&#xff08;八&#xff09;Learning Event-Driven Video Deblurring and Interpolation 前言Abstract1 Introduction2 Motivation2.1 Physical Model of Event-based Video Reconstruction2.2 Spatially Variant Triggering Threshold 3 Proposed Methods3.1 …

无涯教程-Android - List fragments函数

框架的ListFragment的静态库支持版本&#xff0c;用于编写在Android 3.0之前的平台上运行的应用程序&#xff0c;在Android 3.0或更高版本上运行时,仍使用此实现。 List fragment 的基本实现是用于创建fragment中的项目列表 List in Fragments 示例 本示例将向您说明如何基于…

如何在windows下使用masm和link对汇编文件进行编译

前言 32位系统带有debug程序&#xff0c;可以进行汇编语言和exe的调试。但真正的汇编编程是“编辑汇编程序文件(.asm)->编译生成obj文件->链接生成exe文件”。下面&#xff0c;我就来说一下如何在windows下使用masm调试&#xff0c;使用link链接。 1、下载相应软件 下载…

gif怎么转换成mp4格式视频

gif怎么转换成mp4格式视频&#xff1f;GIF格式是一种广泛应用的公用图像文件格式标准&#xff0c;具有许多优势。它占用的内存较小&#xff0c;可以实现自动循环播放&#xff0c;并且兼容多个平台。然而&#xff0c;GIF格式也存在一些缺点。例如&#xff0c;它无法处理复杂的图…

如何提高工业网关的数据传输速度?

工业网关是工业物联网系统中不可或缺的设备&#xff0c;提高工业网关的数据采集、传输速度&#xff0c;是保障和优化物联网系统运营效率的基础。如何提高工业物联网关的数据传输速度&#xff1f;本篇就为大家简单介绍一下。 1、选用高品质网络设备 选用具有足够带宽容量的高质…

hive问题总结

往往用了很久的函数却只知道其单一的应用场景&#xff0c;本文将不断完善所遇到的好用的hive内置函数。 1.聚合函数或者求最大最小值函数搭配开窗函数使用可以实现滑动窗口 例&#xff1a; collect_list函数&#xff0c;搭配开窗函数&#xff0c;实现了在滑动窗口内对事件路径…

idea 常用插件和常用快捷键 - 记录

idea 常用插件 记得下载插件完成后&#xff0c;点击 Apply 和 OK Alibaba Java Coding Guidelines 作用&#xff1a;使用该插件可以&#xff0c;自动提示相关的语法格式问题&#xff0c;格式参考 阿里巴巴代码规范 详情链接&#xff1a; 代码规范之Alibaba Java Coding G…

js深拷贝三种方法

使用递归函数实现深拷贝 const obj {name: zzz,age: 18,hobby: [篮球, 足球],family: {baby: baby}} // 深拷贝 数组 对象 一定要先筛数组再筛对象,因为万物皆对象function deepcopy(newObj, oldObj) {for (const k in oldObj) {// 判断值是否属于array类if (oldObj[k] i…

深度学习怎么学?

推荐这本小白看的《深度学习&#xff1a;从基础到实践&#xff08;上下册&#xff09;》。 深度学习&#xff1a;从基础到实践&#xff08;上下册&#xff09; 深入浅出的讲述了深度学习的基本概念与理论知识&#xff0c;不涉及复杂的数学内容&#xff0c;零基础小白也能轻松掌…

2023-8-31 Dijkstra求最短路(二)

题目链接&#xff1a;Dijkstra求最短路 II #include <iostream> #include <cstring> #include <algorithm> #include <vector> #include <queue>using namespace std;typedef pair<int, int> PII;const int N 150010;int n, m; int h[N…

QT Creator工具介绍及使用

一、QT的基本概念 QT主要用于图形化界面的开发&#xff0c; QT是基于C编写的一套界面相关的类库&#xff0c;如进程线程库&#xff0c;网络编程的库&#xff0c;数据库操作的库&#xff0c;文件操作的库等。 如何使用这个类库&#xff1a;类库实例化对象(构造函数) --> 学习…

数据结构(Java实现)-二叉树(上)

树型结构 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。 有一个特殊的结点&#xff0c;称为根结点&…