代码随想录第三天 | 链表
文章目录
- 链表理论知识
- 定义链表
- 删除链表
- Leetcode203 移除链表元素
- 代码实现
- Leetcode707 设计链表
- 代码实现
- 复杂度分析
- 错误点
- Leetcode206 反转链表
- 新建链表
- 双指针法
链表理论知识
链接: https://programmercarl.com/%E9%93%BE%E8%A1%A8%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html#%E9%93%BE%E8%A1%A8%E7%9A%84%E7%B1%BB%E5%9E%8B
定义链表
// 单链表的节点定义
struct ListNode {int data; // 节点上存储的元素ListNode *next; // 指向下一个节点的指针ListNode(int val) : data(val), next(nullptr) {} // 节点的构造函数
};// 双链表的节点定义
struct DoublyLinkedListNode {int data;DoublyLinkedListNode * prev;DoublyLinkedListNode * next;DoublyLinkedListNode(int val): data(val), prev(nullptr), next(nullptr) {}
};// 新建一个节点
ListNode* head = new ListNode(5);
删除链表
需手动释放这个D节点,释放这块内存
链表的增添和删除都是O(1)操作,也不会影响到其他节点. 如果删除最后一个节点,需要从头节点查找到第四个节点通过next指针进行删除操作,查找的时间复杂度是O(n)
// 删除头节点
ListNode * tmp = head;
head = head->next;
delete tmp;
Leetcode203 移除链表元素
链接: https://leetcode.cn/problems/remove-linked-list-elements/description/
代码实现
ListNode* removeElements(ListNode* head, int val) {// 循环删除满足要求的头节点while (head != nullptr && head->val == val) {ListNode * tmp = head;head = head->next;delete tmp;}ListNode* current_node = head;// 该循环内已经包含了最后一个节点需要删除的情况while (current_node != nullptr && current_node->next != nullptr) {if (current_node->next->val == val) {ListNode* tmp = current_node->next;current_node->next = current_node->next->next;delete tmp;} else {current_node = current_node->next;}}return head;
}
Leetcode707 设计链表
链接: https://leetcode.cn/problems/design-linked-list/description/
代码实现
class MyLinkedList {
public:struct ListNode {int val;ListNode * next;ListNode(int data): val(data), next(nullptr) {}};MyLinkedList() {}int get(int index) {if (index >= size_ || index < 0) {return -1;}ListNode* current_node = head_;while (index-- > 0) {current_node = current_node->next;}return current_node->val;}void addAtHead(int val) {ListNode * new_node = new ListNode(val);new_node->next = head_;head_ = new_node;size_++;}void addAtTail(int val) {ListNode * current_node = head_;if (current_node == nullptr) {addAtHead(val);return;}while (current_node->next != nullptr) {current_node = current_node->next;}ListNode * new_node = new ListNode(val);current_node->next = new_node;size_++;}void addAtIndex(int index, int val) {if (index > size_ || index < 0) {return;}if (head_ == nullptr || index == 0) {addAtHead(val);return;}ListNode * current_node = head_;while (--index > 0) {current_node = current_node->next;}ListNode * new_node = new ListNode(val);new_node->next = current_node->next;current_node->next = new_node;size_++;}void deleteAtIndex(int index) {if (index < 0 || index >= size_) {return;}if (index == 0) {ListNode * tmp = head_;head_ = head_->next;delete tmp;} else {ListNode * current_node = head_;while (--index > 0) {current_node = current_node->next;}ListNode * tmp = current_node->next;current_node->next = current_node->next->next;delete tmp;}size_--;}// 打印链表void printList() const {ListNode* temp = head_;while (temp != nullptr) {std::cout << temp->val << " <-> ";temp = temp->next;}std::cout << "nullptr" << std::endl;}private:ListNode * head_{nullptr};int size_{0};
};/*** Your MyLinkedList object will be instantiated and called as such:* MyLinkedList* obj = new MyLinkedList();* int param_1 = obj->get(index);* obj->addAtHead(val);* obj->addAtTail(val);* obj->addAtIndex(index,val);* obj->deleteAtIndex(index);*/
复杂度分析
时间复杂度:初始化消耗 O(1),get 消耗 O(index),addAtHead 消耗 O(1),addAtTail 消耗 O(n),其中 n 为链表当前长度,即 addAtHead,addAtTail 和 addAtIndex 已调用次数之和,addAtIndex 消耗 O(index)。
空间复杂度:所有函数的单次调用空间复杂度均为 O(1),总体空间复杂度为 O(n),其中 n 为 addAtHead,addAtTail 和 addAtIndex 调用次数之和。
错误点
- 在调用addAtIndex函数时, 多次向头部插入时出错, 除判断
head_ == nullptr
外还需要判断index == 0
- 插入和删除的while循环条件和get中的条件不同
Leetcode206 反转链表
链接: https://leetcode.cn/problems/reverse-linked-list/description/
代码随想录解析: https://programmercarl.com/0206.%E7%BF%BB%E8%BD%AC%E9%93%BE%E8%A1%A8.html#%E6%80%9D%E8%B7%AF
时间复杂度: O(N)
空间复杂度: O(1)
新建链表
会造成内存浪费
双指针法
需特别注意, 在初始化prev和cur指针后, 需将prev->next更新为nullptr, 避免循环嵌套
ListNode* reverseList(ListNode* head) {if (head == nullptr || head->next == nullptr) {return head;}ListNode * prev = head;ListNode * cur = head->next;prev->next = nullptr;while (cur != nullptr) {ListNode * tmp = cur->next;cur->next = prev;prev = cur;cur = tmp;}return prev;
}
相关文章:
代码随想录第三天 | 链表
文章目录 链表理论知识定义链表删除链表 Leetcode203 移除链表元素代码实现 Leetcode707 设计链表代码实现复杂度分析错误点 Leetcode206 反转链表新建链表双指针法 链表理论知识 链接: https://programmercarl.com/%E9%93%BE%E8%A1%A8%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.h…...

Python编码系列—Python数据可视化:Matplotlib与Seaborn的实战应用
🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中…...

putty中修改默认窗口大小和字体、字号
在WinSCP中调用putty,发现默认窗口太小,字号也很小,非常不友好。现在显示器都是1080p起步,所以很有必要修改之。 以中文版v0.70为例,方法: 1. 点击左上角图标 ,选择下拉菜单中的“修改设置”&…...

Windows下网络编与ESP8266-WiFi通信(win32-API)
一、前言 络编程是指编写程序使不同计算机之间能够通过网络进行通信和数据交换。网络编程涉及使用网络协议和编程接口来建立、管理和终止网络上的数据通信。在这一领域中,TCP/IP协议族是核心组成部分,尤其TCP(传输控制协议)是面向…...
【Golang】golang安装一些依赖包时总是失败
Golang安装一些依赖包失败: 比如安装gin包:go get -u github.com/gin-gonic/gin 可能会报错:连接网络失败、超时等 这时可能需要修改go的环境配置,修改代理即可: go env -w GO111MO…...

ubuntu如何监控Xvfb虚拟显示器
在Ubuntu中监控Xvfb显示器主要涉及到使用VNC服务器来远程访问这个环境。以下是一些基本步骤: 安装Xvfb和相关工具: 使用apt安装Xvfb和x11vnc,x11vnc是一个VNC服务器,可以远程访问Xvfb创建的虚拟桌面环境。 sudo apt-get install xvfb sudo ap…...

小型需求管理软件盘点:8款功能强大的工具
本文介绍了以下8款工具:PingCode、Worktile、易得云、Ping、燃草、Gitee、Monday.com、Slack。 在现代企业管理中,需求管理一直是个让人头疼的问题,特别是对于小型企业来说,选择一款合适的需求管理软件往往比想象中更复杂。如果选…...

Labelme的安装与使用教程
文章目录 一、Labelme是什么?二、安装步骤1.新建虚拟环境2.安装Labelme3.Labelme的使用 三、json2yolo 一、Labelme是什么? Labelme是一个用于图像标注的开源工具,可以实现图像标注、语义分割、实例分割等。 本文记录一下labelme的安装与使…...
C#基础:数据库中使用Linq作分组处理(反射/直接分组)
目录 一、使用反射分组 二、不使用反射分组 三、调用示例 四、代码demo 一、使用反射分组 private static List<GroupList<T>> GetGroupList<T>(List<T> entities, string groupByProperty) {// 获取分组字段的类型var propertyInfo typeof(T).…...

Revite二次开发_使用WPF和WebView2制作一个访问网站的窗口
如果想在revit里打开网页,可以使用WebView2来实现,下面是一个代码示例。 也尝试过使用CefSharp,但由于Revit本身也使用了CefSharp,所以需要根据不同的Revit版本选择适合的CefSharp版本,比较麻烦,所以最好还…...
Java Spring Boot 连接数据库
要在Java Spring Boot应用程序中连接数据库,您需要遵循以下步骤: 1. 添加数据库依赖项:在您的Spring Boot项目中的pom.xml文件中添加数据库依赖项,例如MySQL或PostgreSQL等。例如,如果您要连接MySQL数据库,…...

Java面试八股之消息队列中推模式和拉模式分别有哪些使用场景
消息队列中推模式和拉模式分别有哪些使用场景 消息队列的推模式(Push)和拉模式(Pull)各有不同的使用场景和优缺点。下面我会详细介绍这两种模式及其适用场景: 推模式(Push) 特点:…...
springboot jar是如何启动的
我们先来看一个项目的打完包后的MANIFEST.MF文件: Manifest‐Version: 1.0 Implementation‐Title: spring‐learn Implementation‐Version: 0.0.1‐SNAPSHOT Start‐Class: com.tulingxueyuan.Application Spring‐Boot‐Classes: BOOT‐INF/classes/ Spring‐Bo…...

Android 12系统源码_屏幕设备(二)DisplayAdapter和DisplayDevice的创建
前言 在Android 12系统源码_屏幕设备(一)DisplayManagerService的启动这篇文章中我们具体分析了DisplayManagerService 的启动流程,本篇文章我们将在这个的基础上具体来分析下设备屏幕适配器的创建过程。 一、注册屏幕适配器 系统是在Disp…...
常用Mysql命令
前言 本文列举了一些常见的mysql操作 正文 一、连接和登录 MySQL 1. 使用命令行登录 MySQL 注意:需要将mysql的bin目录导入到环境变量中 mysql -u 用户名 -p示例: mysql -u root -p执行上述命令后,系统会提示输入密码,输入…...

IDEA Debug工具
一、Debug工具栏 自定义debug工具栏:先把debug程序运行起来->右击->配置 常用的工具: 二、DeBug常用图标详解 三、DeBug实践操作 常规Debug:略。 Stream Chain:处理流式语句 Reset Frame:重置方法入栈 …...
ARM64的汇编资源
最近在写一本ARM64的教材,所以在晚上查找了一下相关资源,都是免费开源的,不包括盗版书籍。 Exploring AArch64 assembler Roger Ferrer Ibez的博客文章,写在2016-2017年,内容简单充实,适合入门。 《ARM6…...

实验室安全分级分类管理系统在高校中的具体应用
盛元广通高校实验室安全分级分类管理系统的构建,旨在通过科学合理的管理手段,提高实验室的安全水平,保障师生的人身安全,防止实验事故的发生。这一系统通常包括实验室安全等级评估、分类管理、风险控制、安全教育与培训、应急响应…...

使用 prerenderRoutes 进行预渲染路由
title: 使用 prerenderRoutes 进行预渲染路由 date: 2024/8/20 updated: 2024/8/20 author: cmdragon excerpt: prerenderRoutes 函数是 Nuxt 3 中一个强大的工具,它能够帮助开发者优化页面加载速度和改善用户体验。通过使用 prerenderRoutes,你能够灵活地指定需要预渲染的…...

【深度解析】WRF-LES与PALM微尺度气象大涡模拟
查看原文>>>【深度解析】WRF-LES与PALM微尺度气象大涡模拟 针对微尺度气象的复杂性,大涡模拟(LES)提供了一种无可比拟的解决方案。微尺度气象学涉及对小范围内的大气过程进行精确模拟,这些过程往往与天气模式、地形影响和…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...

Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...
微服务通信安全:深入解析mTLS的原理与实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言:微服务时代的通信安全挑战 随着云原生和微服务架构的普及,服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...