Java数据结构中链表分割及链表排序使用快速排序、归并排序、集合排序、迭代、递归,刷题的重点总结
本篇主要介绍在单链表进行分割,单链表进行分隔并使用快速排序、归并排序、集合排序、迭代、递归等方法的总结,愿各位大佬喜欢~~
86. 分隔链表 - 力扣(LeetCode)
148. 排序链表 - 力扣(LeetCode)
目录
一、分隔链表
二、排序链表
2.1先介绍一个最容易最简单的方法
2.2普通归并排序(自顶向下)
2.3借鉴大佬的归并排序(自底向上也是最难的,空间复杂度o(1))
2.4面试官让你用快排实现,不会做也得会
2.5快排2:
一、分隔链表
86. 分隔链表 - 力扣(LeetCode)
给你一个链表的头节点
head和一个特定值x,请你对链表进行分隔,使得所有 小于x的节点都出现在 大于或等于x的节点之前。在分隔链表时,先考虑如何去分隔链表,怎么保证节点的next不形成环。

方法一:也是笨方法,找到第一个>x的值将小的值都逐个进行头插,随后将next指向第一个>x的值
class Solution {public ListNode partition(ListNode head, int x) {if (head == null || head.next == null) {return head;}ListNode mark = new ListNode(0, head);ListNode cur1 = mark;while (cur1.next != null && cur1.next.val < x) {cur1 = cur1.next;}ListNode firstMaxOrNull = cur1.next;ListNode cur2 = cur1;while (cur2 != null && cur2.next != null) {if (cur2.next.val >= x) {cur2 = cur2.next; } else {cur1.next = cur2.next;cur2.next = cur2.next.next;cur1 = cur1.next;cur1.next = null;}}cur1.next = firstMaxOrNull;return mark.next;}
}
方法二:创建俩个链表进行分别插入,最后合并俩个链表
public ListNode partition(ListNode head, int x) {ListNode minLink = new ListNode(0);//记录小值链表的头ListNode minP = minLink;//对小表操作用的指针ListNode maxLink = new ListNode(0);//记录大值链表的头ListNode maxP = maxLink;//同理while(head!=null){if(head.val < x){//找到小的值minP.next = head;//放入minLink中,操作指针后移一位minP = head;}else{maxP.next = head;//放入maxLink中,操作指针后移一位maxP = head;}head = head.next;}//遍历完成后记得后一段链表的最后节点指向null;maxP.next = null;//两段拼接minP.next = maxLink.next;return minLink.next;}
二、排序链表
148. 排序链表 - 力扣(LeetCode)
给你链表的头结点
head,请将其按 升序 排列并返回 排序后的链表 。上一道题并没有让合并之后还要进行排序,本题不仅要分隔之后还要进行排序,此时可以想到很多种方法,比如堆排序,快速排序,归并排序等等。看似简单,却是很多大厂的面试题。

2.1先介绍一个最容易最简单的方法
都存到集合中,排序后再进行赋值,如果写出这样,面试可能要回家喽!!!
class Solution {//思路,先把链表存到数组,排序后重新更新链表public ListNode sortList(ListNode head) {ArrayList<Integer> list = new ArrayList();ListNode p = head;while(p != null){list.add(p.val);p = p.next;}Collections.sort(list);p = head;for(int i = 0;i<list.size();i++){p.val = list.get(i);p = p.next;}return head;}
}
2.2普通归并排序(自顶向下)
使用快慢指针进行找到中间节点,然后进行归并排序
public ListNode sortList(ListNode head){return mergeSort(head);
}// 找到一个链表的中点public ListNode findMid(ListNode head) {if (head == null) return head;ListNode fast = head.next; // 快指针 每次走2步ListNode slow = head; // 慢指针 每次走1步while (fast != null && fast.next != null) {fast = fast.next.next;slow = slow.next;}return slow;}public ListNode mergeSort(ListNode head) {// 当head.next==null时 说明当前链表只有一个元素 无序再排序if (head == null || head.next == null) {return head;}// 找到中间节点ListNode mid = findMid(head);// 存储中间节点的下一个结点ListNode next = mid.next;// 从中间结点断开 分别对两边进行mergeSortmid.next = null;// 返回排序后的头节点ListNode left = mergeSort(head);ListNode right = mergeSort(next);// 返回合并之后的头节点return merge(left, right);}public ListNode merge(ListNode l1, ListNode l2) {ListNode dummy = new ListNode(-1);ListNode curr = dummy;while (l1 != null && l2 != null) {if (l1.val < l2.val) {curr.next = l1;l1 = l1.next;} else {curr.next = l2;l2 = l2.next;}curr = curr.next;}if (l1 != null) {curr.next = l1;}if (l2 != null) {curr.next = l2;}return dummy.next;}
2.3借鉴大佬的归并排序(自底向上也是最难的,空间复杂度o(1))
class Solution {public ListNode sortList(ListNode head) {ListNode dummy = new ListNode(-1, head);// 获取链表的长度int len = 0;ListNode curr = head;while (curr!=null) {len++;curr = curr.next;}// 循环遍历// 外层遍历step 内层处理每step个元素进行一次mergefor (int step=1; step<len; step*=2) {ListNode tail = dummy;curr = dummy.next;while (curr!=null) {ListNode left = curr;ListNode right = cut(left, step);curr = cut(right, step);tail.next = merge(left, right);while (tail.next!=null) {tail = tail.next;}}}return dummy.next;}// 将链表从from开始切掉前step个元素,返回后一个元素public ListNode cut(ListNode from, int step) {step--;while (from!=null && step>0) {from = from.next;step--;}if (from==null) {return null;} else {ListNode next = from.next;from.next = null;return next;}}// 将两个有序链表合并成一个,返回合并后的头节点public ListNode merge(ListNode l1, ListNode l2) {ListNode dummy = new ListNode();ListNode curr = dummy;while (l1!=null && l2!=null) {if (l1.val<l2.val) {curr.next = l1;l1 = l1.next;} else {curr.next = l2;l2 = l2.next;}curr = curr.next;}if (l1!=null) {curr.next = l1;}if (l2!=null) {curr.next = l2;}return dummy.next;}
}
2.4面试官让你用快排实现,不会做也得会
public ListNode sortList3(ListNode head) {return quickSortLinkedList(head)[0];}public ListNode[] quickSortLinkedList(ListNode head) {if(head == null || head.next == null) return new ListNode[]{head,head};//pivot为head,定义跟踪分割左右两个链表的头尾指针ListNode p = head.next,headSmall= new ListNode(),headBig = new ListNode(),tailSmall = headSmall, tailBig = headBig;//partition操作,以pivot为枢纽分割为两个链表while(p != null){if(p.val < head.val){tailSmall.next = p;tailSmall = tailSmall.next;}else{tailBig.next = p;tailBig = tailBig.next;}p = p.next;}//断开<pivot的排序链表、pivot、>=pivot的排序链表,链表变为三个部分head.next = null;tailSmall.next = null;tailBig.next = null;//递归partitionListNode[] left = quickSortLinkedList(headSmall.next);ListNode[] right = quickSortLinkedList(headBig.next);//如果有<pivot的排序链表、连接pivotif(left[1] != null) {left[1].next = head;}//连接pivot、>=pivot的排序链表head.next = right[0];//确定排序后的头节点和尾节点ListNode newHead,newTail;if(left[0] != null) newHead = left[0];else newHead = head;if(right[1] != null) newTail = right[1];else newTail = head;//返回当前层递归排序好的链表头节点和尾节点return new ListNode[]{newHead,newTail};}
2.5快排2:
用6个指针,分别指向小于部分的头
h1和尾t1、等于部分的头h2和尾t2、大于部分的头h3和尾t3。
class Solution {public ListNode sortList(ListNode head) {return quickSort(head);}public ListNode quickSort(ListNode head) {if (head==null || head.next==null) {return head;}ListNode h1 = new ListNode();ListNode h2 = new ListNode();ListNode h3 = new ListNode();ListNode t1 = h1;ListNode t2 = h2;ListNode t3 = h3;ListNode curr = head;int pivot = getMid(head).val; // 用中间节点的原因是,如果每次用最左边的结点,对于纯递增和纯递减的case就退化为O(n)while (curr!=null) {ListNode next = curr.next;if (curr.val < pivot) {curr.next = null;t1.next = curr;t1 = t1.next;} else if (curr.val == pivot) {curr.next = null;t2.next = curr;t2 = t2.next;} else {curr.next = null;t3.next = curr;t3 = t3.next;}curr = next;}// < 的链表和 > 的链表分别快排h1 = quickSort(h1.next);h3 = quickSort(h3.next);// h1链表不一定有元素 h2链表一定有元素 先把h2、h3连起来h2 = h2.next;t2.next = h3;// 如果h1链表为空 直接返回h2即可// 否则找到h1链表的结尾,连上h2的头if (h1==null) {return h2;} else {t1 = h1;// 找到t1链表的结尾while (t1.next!=null) {t1 = t1.next;}t1.next = h2;return h1;}}public ListNode getMid(ListNode head) {ListNode fast = head;ListNode slow = head;while (fast!=null && fast.next!=null) {fast = fast.next.next;slow = slow.next;}return slow;}}
相关文章:
Java数据结构中链表分割及链表排序使用快速排序、归并排序、集合排序、迭代、递归,刷题的重点总结
本篇主要介绍在单链表进行分割,单链表进行分隔并使用快速排序、归并排序、集合排序、迭代、递归等方法的总结,愿各位大佬喜欢~~ 86. 分隔链表 - 力扣(LeetCode) 148. 排序链表 - 力扣(LeetCode) 目录 一…...
音视频基础之音频编码原理简介
一:隐蔽信号 数字音频信号如果不加压缩地直接进行传送,将会占用极大的带宽。例如,一套双声道数字音频若取样频率为44.1KHz,每样值按16bit量化,则其码率为: 244.1kHz16bit1.411Mbit/s 如此大的带宽将给信号…...
【Python--XML文件读写】XML文件读写详解
【Python–XML文件读写】XML文件读写详解 文章目录【Python--XML文件读写】XML文件读写详解1. 前言1.1 介绍1.2 用法2. xml文件内容形式3. xml文件读写3.1 项目框架3.1 写入操作(创建)(create_xml.py)3.2 读取操作(解析…...
GNU make 中文手册 第一二章 概述与介绍
一、第一章:概述 准备知识 在开始我们关于 make 的讨论之前,首先需要明确一些基本概念: 编译:把高级语言书写的代码,转换为机器可识别的机器指令。编译高级语言后生成的指令虽然可被机器识别,但是还不能…...
真的了解HashMap、HashSet吗?做一道测试题试试!
本人博客《HashMap、HashSet底层原理分析》,可以了解hashmap的底层源码实现 测试代码 HashSet底层实际就是一个Hashmap。猜猜下面源码每一个打印结果。 注:user对象重写的hashcode方法,保证name和age一样的情况下hashcode是一样的ÿ…...
树莓派下安装OpenEuler
openEuler作为华为开源的应用于嵌入式设备的操作系统,正在受到越来越多的关注。树莓派是一个很好的应用场景,这篇文章就介绍下如何在树莓派上安装openEuler。 ps:openEuler要求树莓派的版本是4B 1.下载openEuler镜像 镜像网址࿱…...
VSCode Remote-SSH配置免密登录踩坑
VSCode Remote-SSH配置免密登录踩坑1. 参考2. 基本流程2.1 机器A(Windows客户端)2.2 机器B(Linux服务器)2.3 机器A(Windows客户端)的VSCode设置3. 踩坑总结相关教程很多,但要么冗余,…...
【Python语言基础】——Python NumPy 数组拆分
Python语言基础——Python NumPy 数组拆分 文章目录 Python语言基础——Python NumPy 数组拆分一、Python NumPy 数组拆分一、Python NumPy 数组拆分 拆分 NumPy 数组 拆分是连接的反向操作。 连接(Joining)是将多个数组合并为一个,拆分(Spliting)将一个数组拆分为多个。…...
虹科资讯| 虹科AR荣获汽车后市场“20佳”维修工具评委会提名奖!
2022 虹科荣获20佳维修工具 评委会提名奖 特大喜讯,在2月16日《汽车维修与保养》杂志主办的第十八届汽车后市场“20佳”评选活动中,虹科的产品“M400智能AR眼镜”凭借在AR领域的专业实力,通过层层筛选,在102款入围产品中脱颖而出…...
Mysql架构与内部模块
Mysql架构与内部模块 演示环境: MySQL 5.7 存储引擎:InnoDB 一、一条查询SQL是如何执行的? 程序或者工具要操作数据库,第一步跟数据库建立连接。 1、通信协议 首先,MySQL 必须要运行一个服务,监听默认的…...
从技术上来看,互联网技术开始衍生和蜕变出更多的新技术
很多人在看待产业互联网的问题上,一味地割裂它与互联网之间的联系,甚至还有人将产业互联网看成是对于传统互联网的颠覆。如果仅仅只是以这样的眼光来看待产业互联网,那么,他们势必是无法完整把握产业互联网的本质内涵和原始奥义的…...
最长不含重复字符的子字符串
今天处理一道算法题目,《剑指Offer》第48题,力扣中等题。 这道题也是面试的高频题! 题目描述 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。 示例1: 输入: "abcabcbb" …...
git中git push origin master推送远程操作失败,报错解决方案
报错图片如下所示: 解决方案: 使用下面代码进行本地与远程仓库的链接: git remote add origin http://xxxxx///xxx(https://gitee.com/peach-fog/shopping-cart-car-warehouse.git)链接完成之后就会输出:fatal: remote origin already exists. 链接完成之后就需要使用git br…...
服务器部署流程与经验记录
服务器部署流程1.项目部署1.1 重置实例密码1.2 配置安全组规则1.3 远程连接服务器1.4 安装所需软件1.5 安装Tomcat1.6 配置宝塔安全组1.7 导入数据库和项目2. 域名注册3. 网站备案1.项目部署 1.1 重置实例密码 1.2 配置安全组规则 1.3 远程连接服务器 使用VNC远程连接&#…...
超火的情感视频短视频账号,赚钱的路子有多野?
目录 一、情感类视频内容模式 1、线上情感导师型 2、用动画传达人生哲理 3、网抑云式的野生“文案馆” 4、星座式情感账号 二、情感号变现方式 1、首先是可以接广告 2、收徒做情感号培训,知识付费 3、导流粉丝到公众号 4、通过卖号来变现 6、导流微信变现…...
Linux系列 linux 常用命令(笔记)
作者简介:一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页 目录 前言 一.linux 常用命令(目录文和件基本操作) 1.命令的分类…...
Cosmos 基础教程(二)-- Run a Node, API, and CLI
有很多不同的方法来运行Cosmos区块链的节点。您将探索如何使用simapp 进行此操作。 1、编译simapp Cosmos SDK存储库包含一个名为 simapp 的文件夹。在这个文件夹中,您可以找到运行Cosmos SDK模拟版本的代码,这样您就可以在不实际与链交互的情况下测试…...
C# 读写xml文件总结 [详细]
C# 读写xml文件总结C#写入xml文件1、XmlDocument2、DataSet对象里的值来生成XML文件3、利用XmlSerializer来将类的属性值转换为XML文件的元素值。示例:写入xml1、创建xml文档2 、增加节点3 、修改节点:4 、删除节点c#读取xml文件C#写入xml文件 1、XmlDo…...
【Java基础】IO流
IO流 最后一定要关闭流,防止资源泄露 字节流 一次读取1字节,8比特 FileInputStream import org.junit.jupiter.api.Test;import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException;public class CopyBytes {pub…...
Boolean,Array,Object数据类型(回顾)
Boolean数据类型范围Boolean(value)Object数据类型特点键值对数组特点类数组特点 Boolean数据类型范围 true,false 链接 Boolean(value) 定义:其他类型转布尔类型 六大假值:false,undefined,null,NaN,0…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
日常一水C
多态 言简意赅:就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过,当子类和父类的函数名相同时,会隐藏父类的同名函数转而调用子类的同名函数,如果要调用父类的同名函数,那么就需要对父类进行引用&#…...
【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...
消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...
