【每日一题】【归并排序/堆排序&虚拟头结点】148. 排序链表-211220/220217【出栈时不断容易产生环状链表!】
给你链表的头结点 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【出栈时不断容易产生环状链表!】的更多相关文章
- 建立链表的虚拟头结点 203 Remove Linked List Element,82,147,148,237
该逻辑对于删除第一个元素不适用. 这样的代码不优美 /** * Definition for singly-linked list. * struct ListNode { * int val; * ...
- 每日一题 - 剑指 Offer 53 - I. 在排序数组中查找数字 I
题目信息 时间: 2019-07-04 题目链接:Leetcode tag:二分查找 哈希表 难易程度:简单 题目描述: 统计一个数字在排序数组中出现的次数. 示例1: 输入: nums = [5,7 ...
- [每日一题]面试官问:Async/Await 如何通过同步的方式实现异步?
关注「松宝写代码」,精选好文,每日一题 时间永远是自己的 每分每秒也都是为自己的将来铺垫和增值 作者:saucxs | songEagle 一.前言 2020.12.23 日刚立的 flag,每日一 ...
- [每日一题]面试官问:谈谈你对ES6的proxy的理解?
[每日一题]面试官问:谈谈你对ES6的proxy的理解? 关注「松宝写代码」,精选好文,每日一题 作者:saucxs | songEagle 一.前言 2020.12.23 日刚立的 flag,每日一 ...
- Leetcode刷题之链表增加头结点的前缀节点
链表之增加头结点的前缀节点 在许多链表题中往往需要在题目给的头结点之前增加一个前缀节点 通常在删除链表和头结点需要交换时需要用到这一操作 因为增加这个节点就避免了对删除头结点这种特殊情况的特殊处理 而 ...
- 【剑指Offer】简单部分每日五题 - Day 1
今天开始更新leetcode上<剑指Offer>的题解,先从简单难度开始.预计按下列顺序更新: 简单难度:每日5题 中等难度:每日3题 困难难度:每日1题 17 - 打印从1到最大的n位数 ...
- 【python】Leetcode每日一题-反转链表 II
[python]Leetcode每日一题-反转链表 II [题目描述] 给你单链表的头节点 head 和两个整数 left 和 right ,其中 left <= right .请你反转从位置 ...
- 「每日一题」有人上次在dy面试,面试官问我:vue数据绑定的实现原理。你说我该如何回答?
关注「松宝写代码」,精选好文,每日一题 时间永远是自己的 每分每秒也都是为自己的将来铺垫和增值 作者:saucxs | songEagle 来源:原创 一.前言 文章首发在「松宝写代码」 2020. ...
- 【JavaScript】Leetcode每日一题-二叉搜索树的范围和
[JavaScript]Leetcode每日一题-二叉搜索树的范围和 [题目描述] 给定二叉搜索树的根结点 root,返回值位于范围 [low, high] 之间的所有结点的值的和. 示例1: 输入: ...
- 【python】Leetcode每日一题-旋转链表
[python]Leetcode每日一题-旋转链表 [题目描述] 给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置. 示例1: 输入:head = [1,2,3,4,5] ...
随机推荐
- 创建Elasticsearch集群并为它们配置TLS安全通信
文章转载自:https://elasticstack.blog.csdn.net/article/details/105636302 文章开头讲述的是两台es主机构建一个集群,其中有关的配置可以借鉴 ...
- filebeat知识点
在Filebeat的根目录下,有一个叫做filebeat.yml的文件. filebeat.inputs: - type: log enabled: true paths: - ./sample.lo ...
- Kubernetes生态架构图
图片来源于:https://gitbook.curiouser.top/ 一.kubernetes 集群架构图 二.Openshift or Kubernetes 集群架构图 三.常见的 CI/CD ...
- Nginx配置中一个不起眼字符"/"的巨大作用
文章转载自:https://mp.weixin.qq.com/s/QwsbuNIqLpxi_FhQ5pSV3w Nginx作为一个轻量级的,高性能的web服务软件,因其占有内存少,并发能力强的特点,而 ...
- EasyExcel实现文件导出
官网:https://www.yuque.com/easyexcel/doc/easyexcel 导出 准备工作 引入依赖 <!--EasyExcel相关依赖--> <depende ...
- 分布式存储系统之Ceph集群存储池、PG 与 CRUSH
前文我们了解了ceph集群状态获取常用命令以及通过ceph daemon.ceph tell动态配置ceph组件.ceph.conf配置文件相关格式的说明等,回顾请参考https://www.cnbl ...
- POJ2823 滑动窗口 (单调队列)
来学习一下单调队列: 他只可以从队尾入队,但可以从队尾或队首出队,来维护队列的单调性.单调队列有两种单调性:元素的值单调和元素的下标单调. 单调队列可以用来优化DP.状态转移方程形如dp[i]=min ...
- python中的多线程与多进程
线程概念: 线程也叫轻量级进程,是操作系统能够进行运算调度的最小单位,它被包涵在进程之中,是进程中的实际运作单位. 线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其 ...
- P1886 滑动窗口 /【模板】单调队列 方法记录
原题链接 滑动窗口 /[模板]单调队列 题目描述 有一个长为 \(n\) 的序列 \(a\),以及一个大小为 \(k\) 的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最 ...
- uoj220【NOI2016】网格
刚了几个小时啊,这tm要是noi我怕不是直接滚粗了.我判答案为1的情况试了几种做法,最后终于想到了一个靠谱的做法,然后细节巨多,调了好久,刚拿到97分时代码有6.2KB了,后来发现有些东西好像没啥用就 ...