【算法专题】链表算法题

news2024/9/23 6:28:41

1. 链表常用操作

        相信大家在学习数据结构的过程中已经接触过许多链表相关的题目了,在正式开始刷题之前,我想让大家先回顾一下过去处理链表相关问题时的一些常见操作。        

        首先肯定就是创建新节点了,如果使用C语言编写代码,我们需要自己用malloc函数分配内存,然后手动初始化节点,而使用C++就简单多了,直接new就行。然后是链表的尾插,这也非常简单,我们定义一个tail指针始终指向链表的尾部,当进行尾插时,令链表尾部的next指向尾插的节点,然后tail指针重新指向新的链表尾部即可。还有就是头插,如果我们直接进行头插操作,需要对链表为空的情况进行处理,但如果引入虚拟头节点newhead的话,就可以省去对边界情况的讨论,只需要令新节点指向newhead的next,然后newhead指向新节点,这样就非常方便的实现了头插。

        在这里我还想讲一些做链表题时的常用技巧,首先是画图,这有助于我们直观形象地理解题目,在处理比较复杂地题目时很有帮助;还有就是前面提到过的虚拟头节点,有了虚拟头节点,我们能够省去对许多边界情况的讨论,大大降低了代码编写的复杂程度;最后一点,我们大可不必吝啬定义一些辅助的变量,这能避免我们把自己都搞混乱了,举个例子:

相信大家如果经历过数据结构的卷面考试的话,对这种坑爹的题目肯定是不陌生的,令人看得眼花缭乱,出于考核的目的,这无可厚非,但我们自己写代码就没必要这样折磨自己了吧,直接定义一个next指针,指向prev的next,编写代码将会轻松许多。

2. 两数相加

2. 两数相加 - 力扣(LeetCode)

        本题要求我们将以链表形式逆序储存的两个数字进行相加,经常做加法的同学都知道,这实际上是降低了我们编写代码的难度,因为我们的加法运算本来就是从低位到高位进行的呀。所以我们只需要模拟加法这个过程,对两个链表进行遍历,当两个链表非空时进行相加,为了处理进位的情况,我们可以创建变量t来进行辅助运算,根据加法运算逢十进一的性质,把两个链表元素相加的结果加到t,对t取模10后添加到要返回的链表中,t除以10的结果就是进位数更新到t。只要两个链表有一个不为空或者t不为0,我们就继续运算,直到计算完毕为止。

        正如我们在常用操作那里提到的,要返回的链表我们也可以设置一个虚拟头节点,这有助于我们更轻松地编写代码,在最后,我们还需要把虚拟头节点new出来的空间销毁掉。

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) 
    {
        ListNode *newhead = new ListNode(0);
        ListNode *cur = newhead, *cur1 = l1, *cur2 = l2;
        int t = 0;
        while(cur1 || cur2 || t)
        {
            if(cur1)
            {
                t += cur1->val;
                cur1 = cur1->next;
            }
            if(cur2)
            {
                t += cur2->val;
                cur2 = cur2->next;
            }
            cur->next = new ListNode(t % 10);
            t /= 10;
            cur = cur->next;
        }
        cur = newhead->next;
        delete newhead;
        return cur;
    }
};

3. 两两交换链表节点

24. 两两交换链表中的节点 - 力扣(LeetCode)

        根据题意,我们需要把题目所给链表中的元素按两个一组的形式两两交换,并且不能只是修改链表元素的值,必须进行交换。在这里我们用迭代的方式来解决这道题,并且本题也是可以引入虚拟头节点来方便我们代码编写的。

       

如图所示,如果我们不引入虚拟头节点,最前面的两个节点的交换和后续节点的交换方式是不同的,这是因为此时首个节点并没有前驱节点,那我们就需要先设定好第二个节点作为新的头节点,而后续节点均有前驱节点,不需要进行这个步骤。如果这样的话,我们写代码就会麻烦些,但引入虚拟头节点后,首节点也有了前驱节点,这样我们就能用同一个逻辑处理所有节点了。

        

        如上图所示,画图对交换过程进行模拟,可以发现当next移动到链表尾端时,我们就能把所有符合的节点两两进行交换,接下来只要编写代码实现即可。

class Solution {
public:
    ListNode* swapPairs(ListNode* head) 
    {
        if(!head || !head->next) return head;
        ListNode *newhead = new ListNode(0, head);
        ListNode *prev = newhead, *cur = head;
        while(cur && cur->next)
        {
            ListNode *next = cur->next, *nnext = next->next;
            prev->next = next;
            next->next = cur;
            cur->next = nnext;
            prev = cur;
            cur = nnext;
        }
        return newhead->next;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1942827.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL第一阶段:表关系

表关系 表关系分为一对多、多对多、一对一 表关系之一对一 一对一比如用户和用户的详细内容 一对一关系多用于表拆分,将一个实体中经常要用的字段放在一张表,不经常使用的字段放到另一张表,用于提升查询性能。 实现方式:在任…

你了解你的GD32 MCU系统主频是多少吗 ?

系统时钟是GD32 MCU的时基,可以理解为系统的心跳,片上所有的外设以及CPU最原始的时钟都来自于系统时钟,因而明确当前系统时钟是多少非常重要,只有明确了系统时钟,才能够实现准确的定时、准确的采样间隔以及准确的通信速…

【Git】(基础篇七)—— IntelliJIDEA集成Git

InteliJ IDEA集成Git 现在有很多的集成工具帮助我们写代码,使用这些工具可以帮助我们加速写代码,很多工具也可以集成git,使用图形工具管理git,相信了解了底层运行逻辑的你能够很快地上手使用这些工具,本文以InteliJ I…

嘉立创 | 将所有元件属性中间放置

单击元件属性,按鼠标右键,点击查找 点击查找全部,便选中了所有元件属性 点击布局--属性位置 便可以将属性位置改为中间

销量不振,却逆风提价,出尔反尔的宝马在作茧自缚吗?

撰稿|行星 来源|贝多财经 传统豪华汽车品牌宝马,宣布主动退出价格战。 近日,社交平台上有关宝马涨价的传闻不胫而走,引发众多网友关注。相关报道称,有业内人士在社交平台透露,因价格战导致门店亏损严重,…

Python怎样读取URL生成PDF

1. 安装依赖的exe 需要在这个网址,安装一个exe包,地址:https://wkhtmltopdf.org/ 进入网址后,点这个位置: 选择一个你的操作系统的下载链接: 安装后的exe文件: C:\Program Files\wkhtmltopdf…

C++ 栈( stack )学习

目录 1.栈 2.模拟栈 1.1.入栈( push ) 1.2.出栈( pop ) 1.3.获取栈顶元素( top ) 3.直接使用栈( stack ) 3.1.导入头文件并创建栈 3.2.栈的操作 3.2.1.入栈( push ) 3.2.2.出栈( pop ) 3.2.3.获取栈顶元素( top ) 3.2.4.获取栈中元素个数( size ) 3.2.5.判断栈是否…

【第9章】Spring Cloud之Nacos服务配置

文章目录 前言一、改造前二、服务配置1. 添加依赖2. bootstrap.properties3. Data Id 发布配置4. 项目启动 三、改造后四、更多配置项总结 前言 一、改造前 这是我们之前服务注册和发现时使用的两个服务,在application.yml定义了服务注册的一些配置信息 二、服务…

系统架构设计师①:计算机组成与体系结构

系统架构设计师①:计算机组成与体系结构 计算机结构 计算机的组成结构可以概括为以下几个主要部分:中央处理器(CPU)、存储器(包括主存和外存)、输入设备、输出设备,以及控制器、运算器、总线和…

STM32智能机器人控制系统教程

目录 引言环境准备智能机器人控制系统基础代码实现:实现智能机器人控制系统 4.1 数据采集模块 4.2 数据处理与控制模块 4.3 通信与导航系统实现 4.4 用户界面与数据可视化应用场景:机器人控制与优化问题解决方案与优化收尾与总结 1. 引言 智能机器人控…

js中的“?“/“??“以及“||“的详解(值得收藏)

前言 在JavaScript中,问号(?)通常用于三元运算符,而两个问号(??)则是空值合并运算符,用于在左侧操作数为null或undefined时,返回右侧的操作数。 1、?. (可选链运算符…

NCRE3 1-4 宽带接入技术的基本类型

提示,这一部分内容大多数是记的 xDSL数字用户线技术 分类 按照上行和下行的速率是否相同分类分为速率对称性,速率非对称性 相关缩写 ADSL( 非对称数字用户线) 利用普通电话业务(POTS)方式,提供告诉数字业务,允许保留已有的模拟电话业务的…

【c++】C++类和对象详解(下)

目录 思维导图大纲: const成员函数 取地址运算符重载 再探构造函数-初始化列表 隐式类型转换 c语言中我们了解: c中: 单参数 多参数 防止类型转换 static成员 友元 内部类 匿名对象 对象拷贝时的编译器优化 思维导图…

第11讲:变量的基本

变量的数据类型分为基本数据类型、行生数据类型还有POU实例名三种。 此处主要讨论一下基本数据类型。 基本数据类型的种类 基本数据类型的表示方法 1、布尔型、位串型、常数 2、整数型 (1)有符号整数型 SINT型,INT型,DINT型及LINT型,为有符号整数型,二进制表示的最高…

Aigtek:电压放大器的选型方法有哪些

电压放大器是电子电路中常见的元件,用于将输入电压信号放大到所需的水平。在选择适合特定应用的电压放大器时,需要考虑多个因素,包括性能要求、电源电压、带宽、噪声等。下面安泰电子将详细介绍电压放大器的选型方法,以帮助工程师…

【深入理解SpringCloud微服务】深入理解Eureka核心原理

深入理解Eureka核心原理 Eureka整体设计Eureka服务端启动Eureka三级缓存Eureka客户端启动 Eureka整体设计 Eureka是一个经典的注册中心,通过http接收客户端的服务发现和服务注册请求,使用内存注册表保存客户端注册上来的实例信息。 Eureka服务端接收的…

SQLite读取分析指南:新手也能轻松上手的实用教程

SQLite是一个轻量级的关系型数据库,目前已经更新到SQLite3版本。它不仅具有跨平台的特性而且占用的资源非常低,目标是设计来做嵌入式的。本教程将深入浅出地讲解图形化界面和python脚本来读取sqlite数据库这两种方法,从基础概念到实际应用,step by step地…

Windows定时任务实现关闭和开启声音

目录 1. 下载并放置 nircmd.exe1.1 下载 NirCmd:1.2 放置 nircmd.exe: 2. 定时关闭声音2.1 打开任务计划程序:2.2 创建基本任务:2.3 设置任务名称和描述:2.4 触发器:2.5 操作:2.6 设置程序或脚本…

新手小白的pytorch学习第十弹----多类别分类问题模型以及九、十弹的练习

目录 1 多类别分类模型1.1 创建数据1.2 创建模型1.3 模型传出的数据1.4 损失函数和优化器1.5 训练和测试1.6 衡量模型性能的指标 2 练习Exercise 之前我们已经学习了 二分类问题,二分类就像抛硬币正面和反面,只有两种情况。 这里我们要探讨一个 多类别…

专业护眼灯品牌有哪些?五款爆款护眼灯品牌推荐

在当今时代,电子设备在我们的日常生活中扮演着越来越重要的角色。然而,长时间使用这些设备可能会增加眼睛疲劳和近视的风险。为了解决这一问题,护眼台灯应运而生,并逐渐成为许多家庭和办公室的必需品。面对市场上琳琅满目的护眼台…