【每日一题】【归并排序/堆排序&虚拟头结点】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] ...
随机推荐
- X-Pack:创建阈值检查警报
简单的事情应该简单(Simple things should be simple),这是Elastic {ON} '17的主题之一,Elastics收到了许多关于使用简单易用的UI创建警报的请求.事实 ...
- 2. 在 Kubernetes 上安装 Gitlab
总结: 所需要的三个yaml文件的下载地址:https://files.cnblogs.com/files/sanduzxcvbnm/k8s-gitlab.zip Gitlab官方提供了 Helm 的 ...
- 24_Java8
Java8 一. Java8概述 Java8(又称JDK1.8)是Java语言开发的一个主要版本. Oracle公司于2014年3月18日发布Java8 支持Lambda表达式 函数式接口 新的Str ...
- SpringBoot课程学习(四)
一.profile的多文档配置方式 1.profile文件方式:提供多个配置文件,每个代表一种环境 如: 1.application-dev.properties/yml 开发环境 2.applica ...
- OSS对象存储
OSS对象存储 当项目以微服务搭建时,多个服务往往运行在多台服务器上,此时针对存储文件的获取和保存,难以确定具体的位置: 针对这个问题,一般有两个办法: 搭建独立的文件存储服务器,用 FastDFS等 ...
- Springboot 之 Filter 实现超大响应 JSON 数据压缩
简介 项目中,请求时发送超大 json 数据外:响应时也有可能返回超大 json数据.上一篇实现了请求数据的 gzip 压缩.本篇通过 filter 实现对响应 json 数据的压缩. 先了解一下以下 ...
- Shading-JDBC、ShadingSphere、ShardingProxy 使用详解
ShadingSphere ShardingSphere是一款起源于当当网内部的应用框架,2015年在当当网内部诞生,2016年由主要开发人员张亮带入京东数科,在国内经历了当当网.电信翼支付.京东数 ...
- Windows活动目录_票据——敬请期待!
票据:域控&域机子之间的信任密钥 [缺省40天更换一次] 域用户登录过程 域用户的账户密码(用信任密钥加密的)传递至域控: 域控验证账户密码成功后,构造域用户SID和组SID(用信任密钥加密的 ...
- 后端框架的学习----mybatis框架(6、日志)
六.日志 如果一个数据库操作,出现了异常,我们需要排错,日志就是最好的帮手 setting设置 <settings> <setting name="logImpl" ...
- python更改文件后缀名
path = '1024.png' extension = 'jpg' for i in range(1,len(path)): if (path[-i] == '.'):#找到后缀初始点 new_p ...