LeetCode经典题之876、143 题解及延伸

系列目录

88.合并两个有序数组
52.螺旋数组
567.字符串的排列
643.子数组最大平均数
150.逆波兰表达式
61.旋转链表
160.相交链表
83.删除排序链表中的重复元素
389.找不同
1491.去掉最低工资和最高工资后的工资平均值
896.单调序列
206.反转链表
92.反转链表II
141.环形链表
142.环型链表


目录

  • 系列目录
  • 876. 链表的中间节点
    • 线性表
  • 143. 重排链表
    • push_back()与emplace_back()
      • push_back()
      • emplace_back()


876. 链表的中间节点

🌟线性表/动态数组+快慢指针

原题链接


C++
若未特殊标明,以下题解均写用C++

方法一 快慢指针
/*** 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* middleNode(ListNode* head) {ListNode *slow = head, *fast = head;// 记得一定要先对fast 进行检查while (fast != nullptr && fast->next != nullptr) {slow = slow->next;fast = fast->next->next;}return slow;}
};

先检查 fast 是为了确保在尝试访问 fast->next 之前,fast 不是 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:ListNode* middleNode(ListNode* head) {// 定义一个类似于数组特性的线性表——支持下标访问vector<ListNode*> a = {head};// a.back()取原线性表的最后一个元素while (a.back()->next != nullptr)a.push_back(a.back()->next);// C++ 默认向下取整return a[a.size() / 2];}
};

注解:

vector<ListNode*> a = {head};

vector的元素为链表的节点ListNode*——这也是我们为什么要nullptr的原因

并创建一个包含单个元素( 即head指针)的vector

若没有{head},则定义的是一个空的容器vector

线性表

定义

  • 线性表( Linear List)是数据结构的一种,它是一个具有相同特性的数据元素的有限序列
  • 数据元素之间的关系是一对一的,即除了第一个和最后一个数据元素之外,其他数据元素都是首尾相接的
  • 线性表的个数n定义为线性表的长度,n=0时称为空表

性质

  1. 集合中必存在唯一的一个“第一元素”:线性表有明确的起始点
  2. 集合中必存在唯一的一个“最后元素”:线性表有明确的终止点
  3. 除最后一个元素之外,均有唯一的后继( 后件):除了最后一个元素,每个元素后面都跟着一个元素
  4. 除第一个元素之外,均有唯一的前驱( 前件):除了第一个元素,每个元素前面都有一个元素
  5. 线性表能够逐项访问和顺序存取:可以按照元素的顺序进行访问和存储

分类

  • 一般线性表:可以自由地进行删除或添加操作
  • 受限线性表:主要包括栈( 后进先出)和队列( 先进先出),对结点的操作有限制

基本操作

  1. MakeEmpty(L):将L变为空表
  2. Length(L):返回表L的长度,即表中元素个数
  3. Get(L, i):返回L中位置i处的元素( 1≤i≤n)
  4. Prior(L, i):取i的前驱元素
  5. Next(L, i):取i的后继元素
  6. Locate(L, x):返回元素x在L中的位置
  7. Insert(L, i, x):在表L的位置i处插入元素x,将原占据位置i的元素及后面的元素都向后推一个位置
  8. Delete(L, p):从表L中删除位置p处的元素
  9. IsEmpty(L):判断L是否为空表

应用场景

  • 通讯录管理:每个联系人作为线性表的一个元素,包含姓名、电话号码、地址等属性
  • 缓存替换算法:如最近最少使用算法(LRU)和先进先出算法(FIFO),使用线性表结构便于对缓存中的数据进行插入、删除和查找操作
  • 任务调度系统:将需要执行的任务按照一定的优先级顺序存储在线性表中
  • 计算机图形学:顶点表用于存储图形模型的顶点信息,每个元素表示一个顶点
  • 公交线路查询系统:线路信息可以用线性表来存储,每个线路作为线性表的一个元素

优点

  • 逻辑结构简单,便于实现和操作
  • 广泛应用于各种实际场景中,是数据处理和存储的基础结构之一





143. 重排链表

🌟线性表/动态数组

原题链接


C++
若未特殊标明,以下题解均写用C++

/*** 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) {// 特况if (head == nullptr) return;// 定义一个空线性表 Linear Listvector<ListNode*> LL;ListNode* node = head;// 将 链表节点 存入 线性表中while (node != nullptr) {LL.emplace_back(node);node = node->next;}// 下标从0开始int i = 0, j = LL.size() - 1;while (i < j) {// 像数组一样 可用下标访问LL[i]->next = LL[j];i ++;// 如LL.size() = 2,提前结束循环if (i == j)break;LL[j]->next = LL[i];// 用完 j 再更新j --;}// 最后别忘了 指向空LL[i]->next = nullptr;}
};

push_back()与emplace_back()

push_back()

push_backstd::vector 的一个成员函数,用于在容器的末尾添加一个元素 当你使用 push_back 时,你需要提供一个与容器内元素类型相同的对象( 或者一个可以隐式转换为该类型的对象) 这个对象会被复制( 如果类型支持复制)或移动( 如果类型支持移动并且提供了右值引用)到容器的末尾

示例:

#include <vector>  
#include <string>  int main() {  std::vector<std::string> vec;  // 使用 push_back 添加一个字符串  std::string str = "Hello";  vec.push_back(str); // 这里可能发生复制或移动操作  // 也可以直接使用临时对象  vec.push_back(std::string("World")); // 这里一定会发生复制操作( 因为我们是用一个右值来初始化一个临时对象)  return 0;  
}

在上面的例子中,当你使用 push_back 并传递一个 std::string 对象时,如果 str 是一个左值( 即具有持久身份的对象),那么它可能会被复制或移动( 取决于 std::string 的实现和编译器优化) 如果你传递一个右值( 如临时对象),那么通常会发生复制操作,因为右值通常不被视为可移动的对象( 尽管在某些情况下,编译器可能会进行优化以消除不必要的复制)


emplace_back()

emplace_back 是 C++11 引入的一个成员函数,旨在提供比 push_back 更高的性能 与 push_back 不同,emplace_back 允许你直接在容器的末尾构造一个元素,而不是先创建一个对象然后将其复制或移动到容器中 这通常可以避免不必要的复制或移动操作,尤其是在处理大型或复杂的对象时

emplace_back 接受与要构造的对象构造函数相同的参数,并在容器的末尾直接调用该构造函数

示例:

#include <vector>  
#include <string>  int main() {  std::vector<std::string> vec;  // 使用 emplace_back 直接在容器末尾构造一个字符串  vec.emplace_back("Hello"); // 直接在vec的末尾构造一个std::string对象,没有复制或移动  // 也可以传递多个参数给构造函数  vec.emplace_back(5, 'a'); // 构造一个包含5个'a'字符的std::string对象  return 0;  
}

在上面的例子中,emplace_back 直接在 vec 的末尾构造了一个 std::string 对象,没有涉及任何复制或移动操作
这通常比使用 push_back 并传递一个临时对象更高效

总结:

push_backemplace_back 都用于在 std::vector 的末尾添加元素,但 emplace_back 通过直接在容器中构造元素来避免不必要的复制或移动操作,从而可能提供更高的性能

虽然 emplace_back 通常比 push_back 更高效,但在某些情况下(特别是当元素类型支持移动语义且移动操作比复制操作更快时),push_back 可能会使用移动操作来优化性能
然而,emplace_back 仍然是一个很好的选择,特别是当对象的构造过程涉及多个参数或复杂逻辑时

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

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

相关文章

paddleocr查看标注好的数据错误信息

字符计数 import os import json from collections import Counter# 按字符计数 label_dir"/Users/thy/Downloads/chinese20240613" zi_ls[] with open(os.path.join(label_dir,"Label.txt")) as f:linesf.readlines()for line in lines:line line.strip…

Java面试题:聚簇索引和非聚簇索引

聚簇索引和非聚簇索引 聚簇索引(聚集索引) 将数据的存储和索引放在一块,索引结构的叶子节点保存了行数据 索引字段必须存在,且只能存在一个 非聚集索引(二级索引) 将数据和索引分开存储,索引结构的叶子节点关联的是对应的主键 索引字段可以存在多个 索引的选取规则 如果…

【学习】常用的分类网络

1. LeNet 提出时间&#xff1a;1998年最新版本&#xff1a;原始版本使用的数据集格式&#xff1a;MNIST&#xff08;28x28灰度图像&#xff09;优点&#xff1a; 结构简单&#xff0c;易于理解和实现。对于小规模图像数据集&#xff08;如MNIST&#xff09;有很好的表现。缺点…

豆瓣高分项目管理书籍推荐

&#x1f4ec;豆瓣网站上有很多项目管理领域的书籍获得了较高的评分&#xff0c;以下是一些高分项目管理书籍的精选列表&#xff0c;发出来跟大家分享一下&#xff1a; 《项目管理知识体系指南&#xff08;PMBOK指南&#xff09;》 【内容简介】这本书是美国项目管理协会&…

opencv检测图片上七种颜色,分辨颜色和对应位置

opencv检测图片上七种颜色&#xff0c;分辨颜色和对应位置 读取图片&#xff1a;使用cv2.imread()函数读取目标图片。 转换颜色空间&#xff1a;通常在HSV颜色空间中进行颜色检测&#xff0c;因为HSV颜色空间更适合描述颜色的属性。 定义颜色范围&#xff1a;为七种颜色定义…

RabbitMQ 修改默认密码

RabbitMQ的一些常用命令 #启动rabbitmq service rabbitmq-server start# 查看rabbitMQ的运行状态 service rabbitmq-server status# 开启rabbitMQ的后台管理插件 rabbitmq-plugins enable rabbitmq_management # 重启RabbitMQ服务 service rabbitmq-server restart RabbitMQ的…

AcWing 797:差分 ← 一维差分模板题

【题目来源】https://www.acwing.com/problem/content/799/【题目描述】 输入一个长度为 n 的整数序列。 接下来输入 m 个操作&#xff0c;每个操作包含三个整数 l,r,c&#xff0c;表示将序列中 [l,r] 之间的每个数加上 c。 请你输出进行完所有操作后的序列。【输入格式】 第一…

富格林:正规操作实现稳健出金

富格林认为&#xff0c;当下的金融市场&#xff0c;投资者进行理财都会特别关注盈利效率高的产品&#xff0c;而近年来兴起的现货黄金&#xff0c;其高效的盈利效率吸引着大批朋友关注。不过&#xff0c;要想在这盈利出金&#xff0c;就得学习掌握正规的交易策略。下面富格林将…

onnx模型修改:去掉Dropout层

文章目录 尝试1&#xff1a;强行设置dropout层train mode为False尝试2&#xff1a;找到onnx模型中的dropout, train mode设置为False尝试3&#xff1a;直接删除dropout层&#xff0c;连接其输入输出结语 最近训练模型使用了tinyvit&#xff0c;性能挺强的&#xff1a; 但是导出…

超细毛搭配超宽设计,一款更呵护牙龈的牙刷

牙龈敏感的时候&#xff0c;刷牙特别难受&#xff0c;最近试了试惠百施&#xff08;EBISU&#xff09;65孔宽头软毛牙刷&#xff0c;感觉它的口腔护理体验很不错。这款牙刷的设计独特&#xff0c;采用宽头设计&#xff0c;一次就能刷两排牙齿&#xff0c;极大地提高了清洁效率。…

RS232自由转Profinet协议网关模块连接1200PLC与扫码枪通讯及手动清零案例

一、RS232和Profinet这两种通讯接口的特点和应用场景&#xff1a; RS232是一种串行通讯接口标准&#xff0c;常用于连接计算机和外部设备&#xff0c;传输速率较低但稳定可靠。Profinet则是一种工业以太网通讯协议&#xff0c;具有高速、实时性强的特点&#xff0c;适用于工业…

C/C++语言通过动态链表实现按需内存分配和使用(Linux Ubuntu 24.04环境)

我认为比较理想的内存使用方式应该实现这几个特性&#xff1a; 1. 分配一块能满足大多数情况下需求的内存&#xff0c;比如80%的情况下都不需要再次分配内存。 2. 对另外20%需要较多内存的情况&#xff0c;可以通过动态链表按需追加新的内存块。 3. 要对总共消耗的内存有一个…

【C语言】解决C语言报错:Dangling Pointer

文章目录 简介什么是Dangling PointerDangling Pointer的常见原因如何检测和调试Dangling Pointer解决Dangling Pointer的最佳实践详细实例解析示例1&#xff1a;释放内存后未将指针置为NULL示例2&#xff1a;返回指向局部变量的指针示例3&#xff1a;指针悬空后继续使用示例4&…

引领未来:AI Native与物联网(IoT)的革命性融合

引领未来&#xff1a;AI Native与物联网(IoT)的革命性融合 在数字化转型的浪潮中&#xff0c;AI Native作为一种新兴的软件开发模式&#xff0c;正逐渐成为推动技术创新的核心力量。与此同时&#xff0c;物联网(IoT)技术通过连接物理世界与数字世界&#xff0c;不断扩展其应用…

自编码器笔记

编码器解码器自编码器 先压缩特征&#xff0c;再通过特征还原。 判断还原的和原来的是否相等 encode data 在一个“潜在空间”里。它的用途是“深度学习”的核心-学习数据的特征并简化数据表示形式以寻找模式。 变分自编码器&#xff1a; 1. 首先、假设输入数据是符合正态分布…

tiny-redis 项目可能的问题

https://build-your-own.org/redis/ 事件循环怎么实现的 首先我将连接包装为一个 Connect 类&#xff0c;它包含了 socket fd&#xff0c;读写缓冲区&#xff0c;连接状态&#xff08;这个连接是发送数据还是接收数据&#xff09;等成员属性 我会在全局维护一个从 socket fd…

003 选择排序

文章目录 先挑最值&#xff0c;再把剩下的挑最值&#xff0c;再把剩下的挑最值。。。 -- 排序函数 function selectionSort(arr) -- 外层循环&#xff0c;从数组的第一个元素开始&#xff0c;对每个元素进行排序 for i 1, #arr do -- 假设当前位置的元素是最小的 local …

LCR 060. 前 K 个高频元素

给定一个整数数组 nums 和一个整数 k &#xff0c;请返回其中出现频率前 k 高的元素。可以按 任意顺序 返回答案。 示例 1: 输入: nums [1,1,1,2,2,3], k 2 输出: [1,2] 示例 2: 输入: nums [1], k 1 输出: [1] 提示&#xff1a; 1 < nums.length < 105k 的取值范…

【SQL Server点滴积累】Setup SQL Server 2008 Database Mirror (二)

【SQL Server点滴积累】Setup SQL Server 2008 Database Mirror (一)-CSDN博客今天分享SQL Server 2008 R2搭建数据库镜像(Database Mirror)https://blog.csdn.net/ncutyb123/article/details/139749117?spm1001.2014.3001.5501本篇Blog基于以上Blog步骤进行SQL Server 2008 R…

python03——文件操作(new)

“变量”open&#xff08;‘文件路径’&#xff0c;‘模式’&#xff09; //注意加引号 “变量”.write( ) //write函数是写的是字符串&#xff0c;如果你写的东西不是字符串&#xff0c;要写成write&#xff08;str&#xff08;。。&#xff09;&#xff09; “变量”.read…