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…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...
