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

「链表」链表原地算法合集:原地翻转|原地删除|原地取中|原地查重 / LeetCode 206|237|2095|287(C++)

概述

对于一张单向链表,我们总是使用双指针实现一些算法逻辑,这旨在用常量级别空间复杂度和线性时间复杂度来解决一些问题。

所谓原地算法,是指不使用额外空间的算法。

现在,我们利用双指针实现以下四种行为。

//Definition for singly-linked list.struct ListNode {int val;ListNode *next;ListNode(int x = 0) : val(x), next(NULL) {}ListNode(int x, ListNode* node) : val(x), next(node) {}};

*注意* :以下算法都暂不考虑动态内存释放问题。

1.原地翻转

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表头。

示例:


 想实现原地翻转,那就改变链表的相对位置关系

我们来想想怎么做:

定义双指针pre=head和cur=head->next,pre总是指向cur的前一个节点。

我们要做的其实就只是把cur转接到head之前即可。

这要分为四步:

①断开cur与下一个节点的链接,用pre来保存cur之后的节点:pre->next=cur->next;

②把cur翻到head之前:cur->next=head;

③现在cur指向的才是head:head=cur;

④让cur继续翻转下一个节点:cur=pre->next;

(pre已经在这个过程中隐式地向前移动了)

这个过程一直程序到cur是nullptr为止。

复杂度

时间复杂度:O(n)

空间复杂度:O(1)

Code

class Solution {
public:ListNode* reverseList(ListNode* head) {if(!head||!head->next)return head;ListNode* pre=head;ListNode* cur=head->next;while(cur){pre->next=cur->next;cur->next=head;head=cur;cur=pre->next;}return head;}
};

2.原地删除

有一个单链表的 head,我们想删除它其中的一个节点 node

给你一个需要删除的节点 node 。你将 无法访问 第一个节点  head

链表的所有值都是 唯一的,并且保证给定的节点 node 不是链表中的最后一个节点。

删除给定的节点。


要直接删除给定的节点,就是给你哪个,我就删哪个

但是单向链表没有前一个节点该怎么删? 

很简单:把给定节点伪装成给定节点下一个节点,然后把下一个节点直接干掉。

直接看Code。 

复杂度

时间复杂度:O(1)

空间复杂度:O(1)

Code

class Solution {
public:void deleteNode(ListNode* node) {node->val=node->next->val;node->next=node->next->next;}
};

3.原地取中

给你一个链表的头节点 head 。删除 链表的 中间节点 ,并返回修改后的链表的头节点 head 。

示例:

 

删除图1的7和图2的3。 


用快慢指针快速找到中间位置

快指针一次两步,慢指针一次一步,快指针走完是慢指针恰好走到要删除的红色节点处。

证明:链表长度为N,快指针走到末尾的时间为T。

Vfast=2VslowT=N/Vfast则Xslow=T*Vslow=N/2

ListNode* slow=head,*fast=head,*pre=nullptr。

维护slow的前一个节点,然后用上一节的原地删除即可。

复杂度

时间复杂度:O(n)

空间复杂度:O(1)

Code

class Solution {
public:ListNode* deleteMiddle(ListNode* head) {if(!head->next)return nullptr;ListNode* slow=head,*fast=head,*pre=nullptr;while(fast&&fast->next){pre=slow;slow=slow->next;fast=fast->next->next;}pre->next=slow->next;return head;}
};

4.原地查重

给定一个包含 n + 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1 和 n),可知至少存在一个重复的整数。

假设 nums 只有 一个重复的整数 ,返回 这个重复的数 。

你设计的解决方案必须 不修改 数组 nums 且只用常量级 O(1) 的额外空间。


这一节其实并不是链表,但是可由数组映射至链表:

我们将任意数组索引i抽象为链表的节点,nums[i]抽象为链表的next指针。

简单理解:num[]是一个函数,他接受一个链表节点,返回的它的next指针(即数组的索引)

*注意*:我们认为数组下标代表链表节点 ,即:i是本链表节点,而nums[i]是下一个链表节点。

那么可以认为我们以某种顺序构建了一张环状链表:因为某两个位置的nums[i]指向了相同的节点。

*注意*:链表序并不是原数组序。

这一部分需要讲解:

我们先认为i==0的位置是头节点,也就是1号节点,随后观察:

     i     0 1 2 3 4
nums[i] = [1,3,4,2,2]                       nums[4]=2←---------←↓         ↑                    ↓         ↑
ListNode  0--------->1--------->3--------->2--------→4nums[0]=1  nums[1]=3  nums[3]=2  nums[2]=4

现在我们抽象出了一张假想链表,剩下的判环与找环操作详见上一篇文章: 「链表」Floyd判环法(弗洛伊德判圈法|龟兔赛跑法)判环并公式推导找环 / LeetCode 142(C++)

Code

class Solution {
public:int findDuplicate(vector<int>& nums) {int fast=0,slow=0;do{  slow=nums[slow];fast=nums[nums[fast]];}while(slow!=fast);fast=0;while(slow!=fast){slow=nums[slow];fast=nums[fast];}return slow;}
};

总结

原地算法对空间只有几乎可以忽略不计的要求,这使得在有空间限制条件时原地算法有着广泛的应用。

我们介绍的这四种链表原地算法兼具了良好的空间复杂度和时间复杂度,希望可以启发大家对链表算法的思考。

相关文章:

「链表」链表原地算法合集:原地翻转|原地删除|原地取中|原地查重 / LeetCode 206|237|2095|287(C++)

概述 对于一张单向链表&#xff0c;我们总是使用双指针实现一些算法逻辑&#xff0c;这旨在用常量级别空间复杂度和线性时间复杂度来解决一些问题。 所谓原地算法&#xff0c;是指不使用额外空间的算法。 现在&#xff0c;我们利用双指针实现以下四种行为。 //Definition fo…...

【STM32】SPI通信和RTC实时时钟

个人主页~ SPI通信和RTC实时时钟 SPI通信一、简介二、硬件电路三、基本原理四、SPI时序1、时序基本单元2、时序 五、FLASH操作注意事项1、写入操作2、读取操作 六、SPI外设1、简介2、结构 七、传输方式1、主模式全双工连续传输2、非连续传输 RTC实时时钟一、Unix时间戳二、BKP1…...

DAMA学习笔记(十三)-大数据和数据科学

1.引言 大数据不仅指数据的量大&#xff0c;也指数据的种类多&#xff08;结构化的和非结构化的&#xff0c;文档、文件、音频、视频、流数据等&#xff09;&#xff0c;以及数据产生的速度快。数据科学家是指从从数据中探究、研发预测模型、机器学习模型、规范性模型和分析方法…...

【Java】Java 中的 toLowerCase() 方法详解

我最爱的那首歌最爱的angel 我到什么时候才能遇见我的angel 我最爱的那首歌最爱的angel 我不是王子也会拥有我的angel &#x1f3b5; 张杰《云中的angel》 在 Java 编程中&#xff0c;字符串处理是一个非常常见的任务。为了便于开发者操作和格式化字符串&…...

Linux: 进程概念详解

1. 冯诺依曼体系结构 截至目前&#xff0c;我们所认识的计算机&#xff0c;都是有一个个的硬件组件组成 。 【注意】&#xff1a; a. 这里的存储器指的是内存 b. 不考虑缓存情况&#xff0c;这里的CPU能且只能对内存进行读写&#xff0c;不能访问外设(输入或输出设备) c.外…...

【C++】模板详细讲解(含反向迭代器)

欢迎来到我的Blog&#xff0c;点击关注哦&#x1f495; 前言&#xff1a; C的模板在是泛型编程的重要组成部分&#xff0c;编写在不同类型上工作的代码&#xff0c;而无需为每个类型编写重复的代码&#xff0c;这有助于减少代码冗余并提高代码的可维护性。 模板 模板的介绍 …...

haproxy七层代理详解之-完整安装部署流程及负载均衡实现-及热更新方法

一.负载均衡 1.1负载均衡时什么 负载均衡:Load Balance&#xff0c;简称LB&#xff0c;是一种服务或基于硬件设备等实现的高可用反向代理技术&#xff0c;负载均网络流量等)分担给指定的一个或多个后端特定的服务器或设备&#xff0c;从而提高了衡将特定的业务(web服务、公司…...

C++11 bind

bind bind 用来将可调用对象和参数一起进行绑定。可调用对象包括普通函数、全局函 数、静态函数、类静态函数甚至是类成员函数&#xff0c;参数包括普通参数和类成员。绑定后的 结果&#xff0c;可以使用 std::function 进行保存&#xff0c;并延迟调用到我们需要的时候。 绑…...

LeetCode199 二叉树的右视图

前言 题目&#xff1a; 199. 二叉树的右视图 文档&#xff1a; 代码随想录——二叉树的右视图 编程语言&#xff1a; C 解题状态&#xff1a; 成功解决&#xff01; 思路 二叉树层序遍历问题的变种&#xff0c;右视图即意味着二叉树每层的最后一个节点。 代码 /*** Definiti…...

数据赋能(172)——开发:数据挖掘——影响因素、直接作用、主要特征

影响因素 主要影响因素如下&#xff1a; 数据类型与属性&#xff1a; 数据类型和对象的不同属性会使用不同的数据类型来描述&#xff0c;如年龄可能是整数类型&#xff0c;而生日则是日期类型。数据挖掘时需要对不同的数据类型进行不同的处理&#xff0c;这直接影响到挖掘算法…...

Vue:Vue3-TypeScript-Pinia-Vite-pnpm / 基础项目 / 20240807

一、项目技术栈 / 依赖 序号技术栈版本解释1node20.14.02vue 3.4.31 3vite 5.3.4 4TypeScript 5.2.2 5 types/node 22.0.2 解决TypeScript项目中缺少对应模块的类型定义文件的问题6 element-plus 2.7.8 ui组建7 types/js-cookie js-cookie 3.0.6 3.0.5 8 sass 1.77.8 9 hu…...

windows Qt 录屏 录音

启动录屏录音&#xff1a; connect(&m_Process, &QProcess::readyReadStandardOutput, [&]() {qDebug() << "Standard output:" << QString::fromLocal8Bit(m_Process.readAllStandardOutput()); });connect(&m_Process, &QProcess…...

AAC中的ADTS格式分析

&#x1f60e; 作者介绍&#xff1a;欢迎来到我的主页&#x1f448;&#xff0c;我是程序员行者孙&#xff0c;一个热爱分享技术的制能工人。计算机本硕&#xff0c;人工制能研究生。公众号&#xff1a;AI Sun&#xff08;领取大厂面经等资料&#xff09;&#xff0c;欢迎加我的…...

iOS内存管理---MRC vs ARC

系列文章目录 iOS基础—Block iOS基础—Protocol iOS基础—KVC vs KVO iOS网络—AFNetworking iOS网络—NSURLSession iOS内存管理—MRC vs ARC iOS基础—Category vs Extension iOS基础—多线程&#xff1a;GCD、NSThread、NSOperation iOS基础—常用三方库&#xff1a;Mason…...

【数学分析笔记】第1章第1节:集合(2)

这节我自己补了一些内容&#xff0c;要不然听不太懂陈纪修老师讲的 1. 集合与映射 1.3 子集与真子集 假如有 S \textbf{S} S和 T \textbf{T} T两个集合&#xff0c;其中&#xff0c; S \textbf{S} S的所有元素都属于 T \textbf{T} T&#xff0c;则称 S \textbf{S} S是 T \te…...

大话设计模式:七大设计原则

目录 一、单一职责原则&#xff08;‌Single Responsibility Principle, SRP&#xff09;‌ 二、开放封闭原则&#xff08;‌Open-Closed Principle, OCP&#xff09; 三、依赖倒置原则&#xff08;‌Dependency Inversion Principle, DIP&#xff09; 四、里氏替换原则&am…...

利用多商家AI智能名片小程序提升消费者参与度与个性化体验:重塑零售行业的忠诚策略

摘要&#xff1a;在数字化浪潮席卷全球的今天&#xff0c;零售行业正经历着前所未有的变革。消费者对于购物体验的需求日益多样化、个性化&#xff0c;而零售商则面临着如何将一次性购物者转化为品牌忠诚者的巨大挑战。多商家AI智能名片小程序作为一种新兴的数字营销工具&#…...

Scala 闭包

Scala 闭包 Scala 闭包是一个非常重要的概念&#xff0c;它允许我们创建可以在稍后某个时间点执行的功能片段。闭包是一个函数&#xff0c;它捕获了封闭范围内的变量&#xff0c;即使在函数外部&#xff0c;这些变量也可以在函数内部使用。这使得闭包成为处理异步操作、回调和…...

前端JS总结(中)

目录 前言 正文 对象&#xff1a; 分类&#xff1a; 自定义对象&#xff1a; 内置对象&#xff1a; 重点&#xff1a; 常用内置对象&#xff1a; 字符串对象&#xff1a;String 获取字符串长度&#xff1a; 大小写转换&#xff1a; 获取某个字符&#xff1a; 截取字…...

elasticsearch的match_phrase匹配及其可能导致的查询问题

目录 1.match_phrase使用介绍 2.规避可能产生的查询问题 解决方式 一.查询和索引分词器一致&#xff0c;即都使用max_word或者都使用smart 二.使用slop增加匹配的容忍度 3.参考文档 1.match_phrase使用介绍 elasticsearch的match_phrase查询是全文查询&#xff0c;主要用…...

电解除湿器ROSAHL (电解质膜)的工作原理是什么?电解除湿器推荐?

ROSAHL电解除湿器的核心是固态聚合物电解质&#xff08;SPE&#xff09;膜技术&#xff0c;这是一种通过电化学反应实现除湿的创新方法&#xff0c;它的工作原理可以用"三步走"来概括&#xff1a;① 电解捕获&#xff1a;在3V直流电作用下&#xff0c;除湿器内侧的水…...

2026毕业论文降AI指南:deepseek免费降AI指令+降AI神器测评,有效降低AI率【建议收藏】

快过年了&#xff0c;毕业生们日子并不好过&#xff0c;最近私信里哀鸿遍野。 “学姐&#xff0c;我明明是自己写的&#xff0c;为什么查重报告显示AI率80%&#xff1f;” “救命&#xff0c;用了劣质降AI工具结果语句不通&#xff0c;导师直接退回了……” 这几年AI领域发展…...

PostgreSQL 数据误删 止损操作

一、核心原理&#xff1a;为什么数据能恢复&#xff1f;​ 在 PostgreSQL 中&#xff0c;执行 DELETE 操作后&#xff0c;数据并不会立即从磁盘上物理擦除。PostgreSQL 使用多版本并发控制&#xff08;MVCC&#xff09;机制&#xff0c;删除操作仅仅是给数据行打上了一个“已删…...

多租户下的系统业务开发过程探讨痛

一、背景与问题缘起 MySQL 5.6.51 版本下 2000 万行核心业务表开展新增字段操作&#xff0c;需求为新增BIGINT(19) NOT NULL DEFAULT 0 COMMENT 注释&#xff08;因业务实际需要存储大数值关联字段&#xff09;。 表的核心特性为Java 多线程密集读写&#xff0c;业务请求持续高…...

技术判断力之AI三问涌

认识Pass层级结构 Pass范围从上到下一共分为5个层级&#xff1a; 模块层级&#xff1a;单个.ll或.bc文件 调用图层级&#xff1a;函数调用的关系。 函数层级&#xff1a;单个函数。 基本块层级&#xff1a;单个代码块。例如C语言中{}括起来的最小代码。 指令层级&#xff1a;单…...

小白友好指南:在星图GPU平台无代码体验OpenClaw+Qwen3-32B

小白友好指南&#xff1a;在星图GPU平台无代码体验OpenClawQwen3-32B 1. 为什么选择云端无代码方案&#xff1f; 去年第一次接触OpenClaw时&#xff0c;我花了整整三天时间在本地环境折腾依赖项。从CUDA版本冲突到Python虚拟环境报错&#xff0c;最后连基础命令都无法执行。直…...

CiteSpace实战:如何用WOS数据生成高质量文献知识图谱(含美化技巧)

CiteSpace进阶指南&#xff1a;从WOS数据到学术级知识图谱的实战优化 在科研工作中&#xff0c;一篇优秀的文献综述往往能成为领域研究的"地图"&#xff0c;而知识图谱则是这张地图上最直观的路线标识。作为一款专业的文献计量工具&#xff0c;CiteSpace在学术界已有…...

Mac上通过Homebrew快速部署Miniconda:轻量级Python环境管理指南

1. 为什么选择Miniconda Homebrew组合&#xff1f; 在Mac上管理Python环境就像整理衣柜——你既需要足够的空间存放不同季节的衣服&#xff08;各种Python版本和库&#xff09;&#xff0c;又不想让整个房间被衣柜塞满。这就是为什么我强烈推荐Miniconda和Homebrew这对黄金组合…...

打破输入法壁垒:一站式词库转换解决方案

打破输入法壁垒&#xff1a;一站式词库转换解决方案 【免费下载链接】imewlconverter ”深蓝词库转换“ 一款开源免费的输入法词库转换程序 项目地址: https://gitcode.com/gh_mirrors/im/imewlconverter 你是否曾因更换输入法而不得不放弃积累了多年的个人词库&#xf…...

【Linux篇】应用层自定义协议与序列化

&#x1f4cc; 个人主页&#xff1a; 孙同学_ &#x1f527; 文章专栏&#xff1a;Liunx &#x1f4a1; 关注我&#xff0c;分享经验&#xff0c;助你少走弯路&#xff01; 应用层 我们程序员写的一个个解决我们实际问题, 满足我们日常需求的网络程序, 都是在应用层。 再谈 …...