Leetcode链表问题汇总
目录
- [2. 两数相加](https://leetcode.cn/problems/add-two-numbers/)
- [206. 反转链表](https://leetcode.cn/problems/reverse-linked-list/)
- [206. 反转链表 II](https://leetcode.cn/problems/reverse-linked-list-ii/)
- [19. 删除链表的倒数第 N 个结点](https://leetcode.cn/problems/remove-nth-node-from-end-of-list/)
- [21. 合并两个有序链表](https://leetcode.cn/problems/merge-two-sorted-lists/)
- [61. 旋转链表](https://leetcode.cn/problems/rotate-list/)
- [82. 删除排序链表中的重复元素 II](https://leetcode.cn/problems/remove-duplicates-from-sorted-list-ii/)
- [83. 删除排序链表中的重复元素重复元素](https://leetcode.cn/problems/remove-duplicates-from-sorted-list/)
- [141. 环形链表](https://leetcode.cn/problems/linked-list-cycle/)
- [142. 环形链表 II](https://leetcode.cn/problems/linked-list-cycle-ii/)
- [143. 重排链表](https://leetcode.cn/problems/reorder-list/)
2. 两数相加
比较简单的题目,头结点标示的个位数字,因此直接模拟就可以了。注意链表相关的题目可以添加一个虚拟头节点,用来简化一些边界情况的处理。
/*** 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:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {ListNode* res = new ListNode(-1);ListNode* cur = res;int carry = 0; //进位标示while (l1 || l2) {int v1 = l1 ? l1 -> val : 0;int v2 = l2 ? l2 -> val : 0;int sum = v1 + v2 + carry;carry = sum / 10;cur -> next = new ListNode(sum % 10);cur = cur -> next;if (l1) l1 = l1 -> next;if (l2) l2 = l2 -> next;}if (carry) cur -> next = new ListNode(1);return res -> next;}
};
206. 反转链表
翻转即将所有节点的next指针指向前驱节点。由于是单链表,我们在迭代时不能直接找到前驱节点,所以我们需要一个额外的指针保存前驱节点。同时在改变当前节点的next指针前,不要忘记保存它的后继节点。
其实相当于头插法!
class Solution {
public:ListNode* reverseList(ListNode* head) {ListNode* prev = nullptr;ListNode* cur = head;while (cur) {ListNode* nxt = cur -> next;cur -> next = prev;prev = cur;cur = nxt;}return prev;}
};
还有一种递归的写法:
首先我们先考虑 reverseList 函数能做什么,它可以翻转一个链表,并返回新链表的头节点,也就是原链表的尾节点。
所以我们可以先递归处理 reverseList(head->next),这样我们可以将以head->next为头节点的链表翻转,并得到原链表的尾节点tail,此时head->next是新链表的尾节点,我们令它的next指针指向head,并将head->next指向空即可将整个链表翻转,且新链表的头节点是tail。
class Solution {
public:ListNode* reverseList(ListNode* head) {if (!head || !head->next) return head;ListNode *tail = reverseList(head->next);head->next->next = head;head->next = nullptr;return tail;}
};
206. 反转链表 II
/*** 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:ListNode* reverseBetween(ListNode* head, int left, int right) {ListNode* dummy = new ListNode(-1); // 建立一个虚拟头节点,因为有可能left==1,避免处理边界情况dummy -> next = head;auto a = dummy;for (int i = 0; i < left - 1; i++) a = a -> next; //找到left的前一个节点auto b = a -> next, c = b -> next;//接下来是反转链表的逻辑,要做right - left次for (int i = 0; i < right - left; i++) {auto d = c -> next;c -> next = b;b = c, c = d;}//两头的指针搞正确a -> next -> next = c;a -> next = b;return dummy -> next;}
};
19. 删除链表的倒数第 N 个结点
找到前面的那个点,改掉指针即可。
class Solution {
public:ListNode* removeNthFromEnd(ListNode* head, int n) {ListNode* dummy = new ListNode(-1);dummy -> next = head;// sz: 包含虚拟头结点的整个链表的长度int sz = 0;for (auto p = dummy; p; p = p -> next) sz++;// 倒数第N个节点,也就是正数的(sz+1-n)个点.// 要删除这个点,要先到它前面的那个点,也就是第(sz-n)个点,从dummy开始跳,需要跳(sz-n-1)步auto p = dummy;for (int i = 0; i < sz - n - 1; i++) p = p -> next;p -> next = p -> next -> next;return dummy -> next;}
};
21. 合并两个有序链表
判断大小,直接模拟即可,注意代码的简洁性。
class Solution {
public:ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {ListNode* dummy= new ListNode(-1);ListNode* tail = dummy;while (l1 && l2) {if (l1 -> val < l2 -> val) tail = tail -> next = l1, l1 = l1 -> next;else tail = tail -> next = l2, l2 = l2 -> next;}if (l1) tail -> next = l1;if (l2) tail -> next = l2;return dummy -> next;}
};
61. 旋转链表
相当于把后面一部分的链表拼接到前面
class Solution {
public:ListNode* rotateRight(ListNode* head, int k) {if (!head) return head;int sz = 0; //链表长度ListNode* tail; //当前链表的尾节点for (auto p = head; p; p = p -> next) {tail = p;sz++;}k %= sz;if (!k) return head;auto p = head;//找到前半部分的最后的元素for (int i = 0; i < sz - k - 1; i++) p = p -> next;//把后半部分拼到前面即可//1. 前半部分的尾结点的next指向空//2. 后半部分的尾结点的next指向链表的头结点tail -> next = head;head = p -> next; // 这个是最新的头结点p -> next = nullptr;return head;}
};
82. 删除排序链表中的重复元素 II
类似于双指针,判断一段相等值的个数是只有一个,还是至少两个,来选择不同的策略。注意看代码里的条件判断的部分。
class Solution {
public:ListNode* deleteDuplicates(ListNode* head) {auto dummy = new ListNode(-1);dummy -> next = head;auto p = dummy;while (p -> next) {auto first = p -> next;auto end = first -> next;// 让end走到和first不等的节点while (end && end -> val == first -> val) end = end -> next; // 说明相等这一段只有一个if (first -> next == end) p = p -> next;// 至少有两个,那么跳过这一段else p -> next = end;}return dummy -> next;}
};
83. 删除排序链表中的重复元素重复元素
其实把上面题的else里面改一下就可以了
class Solution {
public:ListNode* deleteDuplicates(ListNode* head) {auto dummy = new ListNode(-1);dummy -> next = head;auto p = dummy;while (p -> next) {auto first = p -> next;auto end = first -> next;while (end && end -> val == first -> val) end = end -> next; if (first -> next == end) p = p -> next;else p -> next -> next = end;}return dummy -> next;}
};
当然也有更简单的写法,思路就是判断一下枚举到的值和当前的值是否相等,只保留不相等的节点
class Solution {
public:ListNode* deleteDuplicates(ListNode* head) {if (!head) return head;auto cur = head;for (auto p = head -> next; p; p = p -> next) {if (p -> val != cur -> val) cur = cur -> next = p;}cur -> next = nullptr;return head;}
};
141. 环形链表
用两个指针从头开始扫描,第一个指针每次走一步,第二个指针每次走两步。如果走到 null,说明不存在环;否则如果两个指针相遇,则说明存在环。
原因:
假设链表存在环,则当第一个指针走到环入口时,第二个指针已经走到环上的某个位置,距离环入口还差 x 步。由于第二个指针每次比第一个指针多走一步,所以第一个指针再走 x步,两个指针就相遇了。
复杂度分析,由于慢指针走的总步数小于链表总长度,复杂度为 O ( N ) O(N) O(N).
class Solution {
public:bool hasCycle(ListNode *head) {if (!head || !head -> next) return false;ListNode* slow = head;ListNode* fast = head -> next;while (slow && fast) {if (slow == fast) return true;slow = slow -> next;fast = fast -> next;if (fast) fast = fast -> next;}return false;}
};
142. 环形链表 II
143. 重排链表
相关文章:
Leetcode链表问题汇总
目录 [2. 两数相加](https://leetcode.cn/problems/add-two-numbers/)[206. 反转链表](https://leetcode.cn/problems/reverse-linked-list/)[206. 反转链表 II](https://leetcode.cn/problems/reverse-linked-list-ii/)[19. 删除链表的倒数第 N 个结点](https://leetcode.cn/p…...

基于卷的磁盘扫描算法设计
1、设计目的 常规情况下,当我们扫描计算机的硬盘时, 通常会使用诸如FindFirstFile/FindNextFile(Windows),或者opendir/readdir(Linux)遍历扫描的目录。 一般情形下,由于文件数量相对较少,文件夹层次低,扫…...

计算机组成原理-存储器概念
计算机组成原理-存储器 存储系统的基本概念 1.层次结构 可以直接被CPU读取: 高速缓存:cache主存储器: 主存和内存 辅助存储器: 辅存和外存 2.分类 1.按层次结构划分 如上面所示 2.按存储介质 半导体存储器磁表面存储器光存储器 3.按信息可更改性 r/w存储器ROM(只读存储器) 4…...

力扣刷题 day54:10-24
1.十进制整数的反码 每个非负整数 N 都有其二进制表示。例如, 5 可以被表示为二进制 "101",11 可以用二进制 "1011" 表示,依此类推。注意,除 N 0 外,任何二进制表示中都不含前导零。 二进制的反…...

Java基础篇 | Java8流式编程
✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: Java从入门到精通 ✨特色专栏…...

SolidworksSimulation完成对压力容器的强度分析
如何通过使用SolidworksSimulation完成对压力容器的分析并查看实 体的膜片应力强度以及弯曲应力强度,操作简单易学,让我们进入到操作界面。 我们以罐体底部实体模型为例,这里已经提前设置好了材料。 点击新算例,选择静应力分析 由…...

【C++】继承 ⑨ ( 继承中成员变量同名的处理方案 )
文章目录 一、继承中成员变量同名的处理方案1、继承中成员变量同名的场景说明2、使用域作用符区分同名成员变量 二、代码示例 - 继承中成员变量同名的处理方案 一、继承中成员变量同名的处理方案 1、继承中成员变量同名的场景说明 子类 继承 父类 的 成员 , 如果 子类 中定义了…...

Python报错:‘EagerTensor‘ object has no attribute ‘reshape‘
在使用RPython时,发现python代码部分报错:‘EagerTensor‘ object has no attribute ‘reshape‘ 如何解决? 使用np.array 转换为array,再进行reshape 参考: ‘EagerTensor‘ object has no attribute ‘reshape‘处…...
docker-compose手册
大家好,我叫徐锦桐,个人博客地址为www.xujintong.com。平时记录一下学习计算机过程中获取的知识,还有日常折腾的经验,欢迎大家访问。 前言 一些自己经常用到的docker-compose知识。 一、运行和启动项目 1.1、docker-compose运行…...
【珠峰 WEB 前端架构师课程】学习笔记 100 篇(完结)
该课程是珠峰姜文老师讲的,个人觉得讲的很不错,一路在 b 站学习下来做了 100 篇的学习笔记,收获颇丰。 该课程主要讲了高阶函数、函数柯里化、发布订阅模式、观察者模式、从 0 到 1 实现一个 promise,co 库的实现、eventloop 执行…...
Java线程中sleep()、wait()、yield()、join()方法的使用
1.sleep() sleep(): sleep 方法属于 Thread 类,该行为中线程不会释放锁,只阻塞线程,让出cpu给其他线程,当达到指定的时间后会自动恢复运行状态继续运行。 2.wait() wait(): 该方法属于 Object 类,在这个过程里线程会…...
【机器学习】数据均衡学习笔记
文章目录 序言1. 样本不均衡2. 样本不均衡的影响以及样本均衡的意义3. 什么时候需要进行样本均衡/数据均衡4. 数据不均衡的解决办法 序言 数据集制作过程中需要关注样本均衡问题,学习笔记,简单记录 1. 样本不均衡 分类任务中不同类别样本数差别很大的…...

【软件教程】如何用C++交叉编译出能在Android运行的ELF程序或so动态库
一、配置NDK交叉编译平台 1. 打开Android的官方ndk下载链接https://developer.android.com/ndk/downloads?hlzh-cn,下载windows 64位ndk环境包。 2. 解压后将具有以下文件的路径加入到系统环境变量。 3. 配置好环境变量,如下图所示,Path中存…...

进阶JAVA篇- Map 系列集合的遍历方法与常用API
目录 1.0 Map 集合的说明 1.1 Map 集合的常用方法 1.2 Map 系列集合的特点 2.0 Map 系列集合的遍历方法(三种方法) 2.1 使用 keySet() 方法遍历 2.2 使用 entrySet() 方法遍历 2.3 使用 forEach() 方法遍历(Java 8) 1.0 Map 集合的…...

Auth.js:多合一身份验证解决方案 | 开源日报 No.60
nodejs/node Stars: 96.2k License: NOASSERTION Node.js 是一个开源的、跨平台的 JavaScript 运行时环境。它具有以下关键特性和核心优势: 强大:Node.js 提供了强大且高效的服务器端运行能力,可以处理并发请求,并支持异步编程…...

SpringBoot整合Activiti7——任务监听器(七)
文章目录 一、任务监听器事件类型配置方式(选)代码实现xml文件创建监听器class方式expression方式delegateExpression 测试流程部署流程启动流程完成任务 一、任务监听器 任务监听器可以在任务创建、任务分配、任务完成、任务删除发生时触发,从而执行相应的逻辑。 事…...

电解电容寿命与哪些因素有关?
电解电容在各类电源及电子产品中是不可替代的元器件,这些电子产品中由于应用环境的原因,使它成为最脆弱的一环,所以,电解电容的寿命也直接影响了电子产品的使用寿命。 一、电解电容失效模式与因素概述 铝电解电容器正极、负极引出…...

Opencv-图像插值与LUT查找表
图像像素的比较 白色是255,黑色是0 min(InputArray src1,InputArray src2,OutputArray dst) max(InputArray src1,InputArray src2,OutpurArray dstsrc1:第一个图像矩阵,通道数任意src2:第二个图像矩阵,尺寸和通道数以及数据类型…...
我为什么写博客?写博客给我带来了什么?
1、写博客的契机 (1)刚开始接触CSDN,是大三的时候开始学习嵌入式开发,经常需要到网上百度查资料,由此经常游览CSDN上的博客; (2)在嵌入式的过程中,需要总结学习过的知识。…...

jdk11的HttpClient
我们都知道在jdk11之前都在用okhttp或者org.apache.httpcomponents 其实早在jdk9的时候这个方案就在孵化中 上面的截图来自openjdk的官网,注:openjdk是个开源项目,不存在侵权现象 这是openjdk的官网:JEP 110: HTTP/2 Client (In…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...

嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...

并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...