当前位置: 首页 > news >正文

【链表】重排链表,看似复杂实则并不简单~

文章目录

  • 143. 重排链表
  • 解题思路

143. 重排链表

143. 重排链表

​ 给定一个单链表 L 的头节点 head ,单链表 L 表示为:

L0 → L1 → … → Ln - 1 → Ln

​ 请将其重新排列后变为:

L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …

​ 不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

示例 1:

在这里插入图片描述

输入:head = [1,2,3,4]
输出:[1,4,2,3]

示例 2:

在这里插入图片描述

输入:head = [1,2,3,4,5]
输出:[1,5,2,4,3]

提示:

  • 链表的长度范围为 [1, 5 * 104]
  • 1 <= node.val <= 1000

解题思路

​ 这道题如果我们直接重排的话,那么时间复杂度比较高,并且程序也比较复杂,所以我们要分解问题来分析!

​ 仔细想想,这道题无非就是让链表从头和从末尾开始每一个节点进行合并,那不就相当于是两个链表的合并操作吗对不对!并且其中一个链表就是原链表中的前半部分,另一个链表是原链表中后半部分的逆序,比如例子中的 1->2->3->4->5,前半部分可以看作是 1->2->3(这道题也可以看作是 1->2,最后合并结果都是一样的),后半部分则是逆序的情况:5->4,此时将它们逐个合并起来就是 1->5->2->4->3 了!

​ 根据上面的解析,我们可以把这道题分为三步来解决:

  1. 找到链表的中间节点(使用快慢指针就能得到,此时 slow 就是中间节点)
  2. 逆序中间节点的右侧链表(可以使用双指针或者头插法,下面再讨论)
  3. 合并左右两个链表

​ 上面的操作我们都是耳熟能详啦,其中要注意的无非就是第二步,这里介绍 头插法的使用,其实就是引入一个新的头节点 newhead,将右侧链表中的节点逐个头插到 newhead 后面,最后得到一个只有后半部分的逆序链表,而原链表中就剩下前半部分!只不过要注意一些细节,下面我们来讨论一下!(至于双指针的做法,这里就不介绍了,其实相对头插法来说没那么好理解!)

​ 因为链表的个数可以为奇数或者是偶数,所以我们要考虑一下中间节点 slow 是否要包括在头插法和逆序的操作中,所以此时我们使用头插法的时候有两种策略:

  1. 将中间节点 slow 后面的链表进行逆序,包括中间节点 slow

    • 其实这种情况下无论是链表个数是奇数还是偶数的话,使用头插法的时候都不太好整,因为可能会出现一些 bug,如下图所示:

      在这里插入图片描述

    • 因为我们最后是要将后半部分单独拎出来作为一个逆序链表,但是此时有一个问题,就是 slow 前面的节点的 next 是指向 slow 的,因为我们要断开左右部分的链接,此时需要将其 slow 前面的节点的 next 置为空,不然在后面合并遍历的时候,就会死循环。但问题是这是一个单链表,要找到前面的节点的话势必要重新遍历,时间复杂度就提高了,所以这种包括中间节点的也一起头插和逆序的操作是 不推荐 的,不如使用下面的策略!

  2. 将中间节点 slow 后面的链表进行逆序,但 不包括中间节点 slow

    • 此时这种情况就比较好办了,无论链表的个数是奇数还是偶数,此时中间节点最后都不属于右半部分的,而是属于前半部分的,那么同样两个链表要断开连接的话,就在中间节点 slow 断开,这就非常简单了,直接就是一个 slow->next = nullptr 就解决了,非常的高效和简单!

      在这里插入图片描述

    • 比如举个例子,如下图所示:

      在这里插入图片描述

​ 此外需要注意的细节就是,在进行逆序头插法的时候,需要先记录一下当前节点的下一个节点,防止指向改变后丢失,其它就没有什么大问题了!

​ 解决了第二步,那么第三步就没问题了,就是要将右侧链表的每个节点插入到左侧链表的每个节点中!下面直接给出代码,具体过程可以结合自己画图来分析,都是不难的,只是流程多而已

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:void reorderList(ListNode* head) {// 1. 找到链表的中间节点ListNode* fast = head;ListNode* slow = head;while(fast != nullptr && fast->next != nullptr){slow = slow->next;fast = fast->next->next;}// 2. 逆序中间节点之后的链表,但不包括中间节点(此时slow就是中间节点)ListNode* newhead = new ListNode(0, nullptr);ListNode* right = slow->next;while(right != nullptr){ListNode* next = right->next; // 先记录下一个节点防止丢失right->next = newhead->next;newhead->next = right;right = next;}// 3. 合并左右两个链表slow->next = nullptr; // 记得要断开左右链表的连接,不然会死循环ListNode* cur1 = head;ListNode* cur2 = newhead->next;while(cur1 != nullptr && cur2 != nullptr){ListNode* next1 = cur1->next;ListNode* next2 = cur2->next;cur1->next = cur2;cur2->next = next1;cur1 = next1;cur2 = next2;}delete newhead; // 别忘了要释放节点}
};

相关文章:

【链表】重排链表,看似复杂实则并不简单~

文章目录 143. 重排链表解题思路 143. 重排链表 143. 重排链表 ​ 给定一个单链表 L 的头节点 head &#xff0c;单链表 L 表示为&#xff1a; L0 → L1 → … → Ln - 1 → Ln​ 请将其重新排列后变为&#xff1a; L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …​ 不能…...

yakit-靶场-高级前端加解密与验签实战(for嵌套纯享版)

高级前端加解密与验签实战 一、前端验证签名&#xff08;验签&#xff09;表单&#xff1a;HMAC-SHA256 使用hmac-sha256的十六进制key值可以加密 与页面加密后的值相同 热加载&#xff1a; encryptData func(p) { //sha256key值key codec.DecodeHex("313233343132333…...

洛谷 P1328 [NOIP2014 提高组] 生活大爆炸版石头剪刀布

题解&#xff1a; #include<iostream> #include<vector> //定义二维数组&#xff0c;直接标识不同出法相应对应关系 int mark[5][5]{{0,-1,1,1,-1},{1,0,-1,1,-1},{-1,1,0,-1,1},{-1,-1,1,0,1},{1,1,-1,-1,0}}; void JudgeScore(int A,int B,int& countA,int&…...

NLP论文速读(NeurIPS 2024)|BERT作为生成式上下文学习者BERTs are Generative In-Context Learners

论文速读|BERTs are Generative In-Context Learners 论文信息&#xff1a; 简介&#xff1a; 本文探讨了在自然语言处理&#xff08;NLP&#xff09;领域中&#xff0c;上下文学习&#xff08;in-context learning&#xff09;的能力&#xff0c;这通常与因果语言模型&#x…...

亚马逊云科技 | Amazon Nova:智能技术新势力

在2024年亚马逊云科技re:invent大会上&#xff0c;Amazon Nova 系列自研生成式 AI 多模态模型重磅登场&#xff0c;新一代的AI产品-Amazon Nova&#xff0c;隶属于 Amazon Bedrock&#xff0c;一共发布6款大模型&#xff0c;精准切入不同领域&#xff0c;解锁多元业务可能&…...

Kali 自动化换源脚本编写与使用

1. 背景与需求 在使用 Kali Linux 的过程中&#xff0c;软件源的配置对系统的更新与软件安装速度至关重要。 Kali 的默认官方源提供了安全且最新的软件包&#xff0c;但有时由于网络条件或地理位置的限制&#xff0c;使用官方源可能会出现速度较慢的问题。 为了解决这一问题&a…...

【已解决】PDF文档有密码怎么办(2024新)免费在线工具PDF2Go

强大的解密工具PDF2Go使用指南 一、PDF2Go简介 PDF2Go是由德国QaamGo公司开发的在线PDF工具箱&#xff0c;以其强大的功能和用户友好的界面而闻名。它不仅免费&#xff0c;而且不需要用户注册或安装任何软件&#xff0c;只需打开浏览器即可使用。 二、功能特点 1. 免费且无需…...

华为ensp-BGP联盟

学习新思想&#xff0c;争做新青年&#xff0c;今天学习BGP联盟 实验介绍 一个BGP联盟是一个具有内部层次结构的AS。一个BGP联盟由若干个子AS 组成&#xff0c;子AS也称为成员AS。对于一个BGP联盟&#xff0c;其成员AS内部的各路由器之间需要建立全互联的IBGP邻居关系或使用B…...

ArcGIS中怎么进行水文分析?(思路介绍)

最近有人咨询&#xff0c;ArcGIS中怎么进行水文分析&#xff0c;大致的说一下河网提取的思路哈 解决思路&#xff1a;dem填洼→计算水流方向→计算水流累积矩阵→形成河网 dem填洼 计算水流方向 计算水流累积矩阵 用栅格计算器&#xff0c;设阈值&#xff08;自己多次尝试&…...

LabVIEW中实现多个Subpanel独立调用同一个VI

在LabVIEW中&#xff0c;如果需要通过多个Subpanel同时调用同一个VI并让这些VI实例独立运行&#xff0c;可以通过以下方法实现&#xff1a; 1. 问题背景 LabVIEW默认的VI是以单实例方式运行的。当将同一个VI加载到多个Subpanel时&#xff0c;会因为共享同一内存空间而导致冲突…...

【SpringMVC】Bean 加载控制

在实际开发中&#xff0c;SpringMVC 负责扫描和加载 Controller 层的 Bean 对象&#xff0c;而业务层和数据层等其他模块的 Bean 则由 Spring 框架负责扫描和加载。那么&#xff0c;如何控制 Spring 仅加载除了 Controller 层之外的其他 Bean 呢&#xff1f;为了解决这个问题&a…...

Socket编程中关于服务器端监听端口与新连接端口的深入剖析

Socket编程中关于服务器端监听端口与新连接端口的深入剖析 在Socket编程领域&#xff0c;存在一个容易让初学者感到困惑的问题。尽管很多人在网络上进行了相关探讨&#xff0c;但不少解释要么不够清晰明了&#xff0c;要么太过肤浅&#xff0c;未能深入到问题的核心&#xff0…...

如何通过HTTP API更新Doc

本文介绍如何通过HTTP API更新Collection中已存在的Doc。 说明 若更新Doc时指定id不存在&#xff0c;则本次更新Doc操作无效 如只更新部分属性fields&#xff0c;其他未更新属性fields默认被置为null 前提条件 已创建Cluster&#xff1a;创建Cluster。 已获得API-KEY&#…...

Qt5 中 QGroupBox 标题下沉问题解决

我们设置了QGroupBox 样式之后,发现标题下沉了,那么如何解决呢? QGroupBox {font: 12pt "微软雅黑";color:white;border:1px solid white;border-radius:6px; } 解决后的效果 下面是解决方法: QGroupBox {font: 12pt "微软雅黑";color:white;bo…...

[OpenGL]使用glsl实现smallpt

一、简介 本文介绍了如何使用 OpenGL&#xff0c;使用 glsl 语言在 Fragment shader 中实现 smallpt。程序完成后可以得到以下渲染结果&#xff08;samples per pixel, spp 16&#xff09;。在程序中按下A,W可以左右平移&#xff0c;按下W,S可以前后平移&#xff1a; 二、s…...

elementui的默认样式修改

今天用element ui &#xff0c;做了个消息提示&#xff0c;发现提示的位置总是在上面&#xff0c;如图&#xff1a; 可是我想让提示的位置到下面来&#xff0c;该怎么办&#xff1f; 最后还是看了官方的api 原来有个自定义样式属性 customClass 设置下就好了 js代码 css代码…...

mysql的主从配置

#mysql数据库 #主从 MySQL数据库主从配置 1.MySQL主从介绍 MySQL 主从又叫做 Replication、AB 复制。简单讲就是 A 和 B 两台机器做主 从后&#xff0c;在 A 上写数据&#xff0c;另外一台 B 也会跟着写数据&#xff0c;两者数据实时同步的。 MySQL 主从是基于 binlog 的&…...

CPO-CNN-GRU-Attention、CNN-GRU-Attention、CPO-CNN-GRU、CNN-GRU四模型多变量时序预测对比

CPO-CNN-GRU-Attention、CNN-GRU-Attention、CPO-CNN-GRU、CNN-GRU四模型多变量时序预测对比 目录 CPO-CNN-GRU-Attention、CNN-GRU-Attention、CPO-CNN-GRU、CNN-GRU四模型多变量时序预测对比预测效果基本介绍程序设计参考资料 预测效果 基本介绍 基于CPO-CNN-GRU-Attention、…...

深入了解PINN:物理信息神经网络(Physics-Informed Neural Networks)

1. 什么是PINN&#xff08;物理信息神经网络&#xff09;&#xff1f; 物理信息神经网络&#xff08;PINN&#xff0c;Physics-Informed Neural Networks&#xff09;是一类通过结合神经网络和物理方程的深度学习方法。其主要特点是将物理系统的约束条件&#xff08;如偏微分方…...

人形机器人全身运动规划相关资料与文章

1.HumanPlus: Humanoid Shadowing and Imitation from Humans 文章地址&#xff1a;[2406.10454] HumanPlus: Humanoid Shadowing and Imitation from Humans 代码地址&#xff1a;MarkFzp/humanplus: [CoRL 2024] HumanPlus: Humanoid Shadowing and Imitation from Humans …...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...