给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。

进阶:

你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?

方法1:归并排序+使用辅助函数

import java.util.*;

/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/ public class Solution {
/**
*
* @param head ListNode类 the head node
* @return ListNode类
*/
public ListNode sortInList (ListNode head) {
return head == null ? null : mergeSort(head);
} public ListNode mergeSort(ListNode head) {
if(head.next == null) {
return head;
}
ListNode slow = head, fast = head;
//需要断开两个链表!!!
ListNode pre = null;
//注意:fast指针判断时要分别判断
while(fast != null && fast.next != null) {
pre = slow;
slow = slow.next;
fast = fast.next.next;
}
pre.next = null; //将链表分成两部分,才能分别递归计算
ListNode left = mergeSort(head);
ListNode right = mergeSort(slow);
return merge(left, right);
} public ListNode merge(ListNode left, ListNode right) {
ListNode dummy = new ListNode(-1);
ListNode cur = dummy;
while(left != null && right != null) {
if(left.val < right.val) {
cur.next = left;
cur = cur.next;
left = left.next;
} else {
cur.next = right;
cur = cur.next;
right = right.next;
}
}
if(left != null) {
cur.next = left;
}
if(right != null) {
cur.next = right;
}
return dummy.next;
}
}

方法2:堆排序&确定虚拟节点

import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/ public class Solution {
/**
*
* @param head ListNode类 the head node
* @return ListNode类
*/
//会超时
public ListNode sortInList (ListNode head) {
PriorityQueue<ListNode> queue = new PriorityQueue<>((o1, o2) -> o1.val - o2.val);
while(head != null) {
queue.offer(head);
head = head.next;
}
//虚拟节点与cur节点的确定
ListNode dummy = new ListNode(-1);
ListNode cur = queue.poll();
dummy.next = cur;
while(!queue.isEmpty()) {
cur.next = queue.poll();
cur = cur.next;
}
     cur.next = null; //入队时next指针存着下一个元素,要断掉指针指向,否则会产生超时(环形链表)
return dummy.next;
}
}

如何确定虚拟头结点和cur节点之间的关系?

前提:head不为空

ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode cur = dummy.next;
ListNode pre = dummy;

方法3:使用Collections集合工具类排序

新建节点并返回

import java.util.*;

/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/ public class Solution {
/**
*
* @param head ListNode类 the head node
* @return ListNode类
*/
//方法3:ArrayList存值后,使用工具类排序,建新节点
public ListNode sortInList (ListNode head) {
if(head == null || head.next == null) {
return head;
}
ListNode cur = new ListNode(0);
ArrayList<Integer> list = new ArrayList<>();
while(head != null) {
list.add(head.val);
head = head.next;
}
Collections.sort(list);
ListNode p = cur;
for(int i = 0; i < list.size(); i++) {
ListNode node = new ListNode(list.get(i));
p.next = node;
p = p.next;
}
return cur.next;
}
}

【每日一题】【归并排序/堆排序&虚拟头结点】148. 排序链表-211220/220217【出栈时不断容易产生环状链表!】的更多相关文章

  1. 建立链表的虚拟头结点 203 Remove Linked List Element,82,147,148,237

    该逻辑对于删除第一个元素不适用. 这样的代码不优美 /** * Definition for singly-linked list. * struct ListNode { * int val; * ...

  2. 每日一题 - 剑指 Offer 53 - I. 在排序数组中查找数字 I

    题目信息 时间: 2019-07-04 题目链接:Leetcode tag:二分查找 哈希表 难易程度:简单 题目描述: 统计一个数字在排序数组中出现的次数. 示例1: 输入: nums = [5,7 ...

  3. [每日一题]面试官问:Async/Await 如何通过同步的方式实现异步?

    关注「松宝写代码」,精选好文,每日一题 ​时间永远是自己的 每分每秒也都是为自己的将来铺垫和增值 作者:saucxs | songEagle 一.前言 2020.12.23 日刚立的 flag,每日一 ...

  4. [每日一题]面试官问:谈谈你对ES6的proxy的理解?

    [每日一题]面试官问:谈谈你对ES6的proxy的理解? 关注「松宝写代码」,精选好文,每日一题 作者:saucxs | songEagle 一.前言 2020.12.23 日刚立的 flag,每日一 ...

  5. Leetcode刷题之链表增加头结点的前缀节点

    链表之增加头结点的前缀节点 在许多链表题中往往需要在题目给的头结点之前增加一个前缀节点 通常在删除链表和头结点需要交换时需要用到这一操作 因为增加这个节点就避免了对删除头结点这种特殊情况的特殊处理 而 ...

  6. 【剑指Offer】简单部分每日五题 - Day 1

    今天开始更新leetcode上<剑指Offer>的题解,先从简单难度开始.预计按下列顺序更新: 简单难度:每日5题 中等难度:每日3题 困难难度:每日1题 17 - 打印从1到最大的n位数 ...

  7. 【python】Leetcode每日一题-反转链表 II

    [python]Leetcode每日一题-反转链表 II [题目描述] 给你单链表的头节点 head 和两个整数 left 和 right ,其中 left <= right .请你反转从位置 ...

  8. 「每日一题」有人上次在dy面试,面试官问我:vue数据绑定的实现原理。你说我该如何回答?

    关注「松宝写代码」,精选好文,每日一题 ​时间永远是自己的 每分每秒也都是为自己的将来铺垫和增值 作者:saucxs | songEagle 来源:原创 一.前言 文章首发在「松宝写代码」 2020. ...

  9. 【JavaScript】Leetcode每日一题-二叉搜索树的范围和

    [JavaScript]Leetcode每日一题-二叉搜索树的范围和 [题目描述] 给定二叉搜索树的根结点 root,返回值位于范围 [low, high] 之间的所有结点的值的和. 示例1: 输入: ...

  10. 【python】Leetcode每日一题-旋转链表

    [python]Leetcode每日一题-旋转链表 [题目描述] 给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置. 示例1: 输入:head = [1,2,3,4,5] ...

随机推荐

  1. 清除已安装的rook-ceph集群

    官方文档地址:https://rook.io/docs/rook/v1.8/ceph-teardown.html 如果要拆除群集并启动新群集,请注意需要清理的以下资源: rook-ceph names ...

  2. Beats:使用Elastic Stack监控RabbitMQ

  3. 【ceph】理解Ceph的三种存储接口:块设备、文件系统、对象存储

    文章转载自:https://blog.51cto.com/liangchaoxi/4049104

  4. SpringBoot项目的CI配置 # 安全变量

    运行GitLab Runner容器 参考Run GitLab Runner in a container - Docker image installation and configuration 执 ...

  5. JSP实现登录功能(页面带样式)

    功能要求 1.完成两个页面 2.第一个登陆页面login. jsp 3.第二个用户管理页面useManage. jsp 4.有登录功能(能进行用户名密码的校验,用户名若为自己的学号密码为班级号,允许登 ...

  6. 条件期望:Conditional Expectation 举例详解之入门之入门之草履虫都说听懂了

    我知道有很多人理解不了 "条件期望" (Conditional Expectation) 这个东西,有的时候没看清把随机变量看成事件,把 \(\sigma\)-algebra 看成 ...

  7. Docker | 容器数据卷详解

    什么是容器数据卷 从docker的理念说起,docker将应用和环境打包成一个镜像,运行镜像(生成容器)就可以访问服务了. 如果数据都存在容器中,那么删除容器,数据就会丢失!需求:数据可以持久化 My ...

  8. linux基础总结

    linux的特点 - 免费的/开源       - 支持多线程/多用户       - 安全性好       - 对内存和文件管理优越 关机命令      shutdown -h now(立即进行关机 ...

  9. 5.ElasticSearch系列之文档的基本操作

    1. 文档写入 # create document. 自动生成 _id POST users/_doc { "user" : "shenjian", " ...

  10. 网页头部的声明应该是用 lang="zh" 还是 lang="zh-CN"?

    网页头部的声明应该是用 lang="zh" 还是 lang="zh-CN"? 遇到问题 不知道大家有没有留意到一个问题,就是使用 VsCode 新建的 html ...