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

代码随想录算法训练营第三天| 链表理论基础 203.移除链表元素 707.设计链表 206.反转链表

文章所有题目链接/文章讲解/视频讲解来源——代码随想录 

链表理论基础

1. 链表是串联起来的,每个节点包含元素和指针
2. 链表包含单链表、双链表、循环链表
3. 链表里的节点不存储在连续空间,而是分散在存储中,用指针指向对应的元素
4. 链表中的操作包含增加、删除、查询,不适用于查询较多的题目
5. 定义链表:


struct ListNode{int val;ListNode* next;//自定义构造函数,如果不自定义则c++默认构造ListNode(int x) : val(x),next(NULL) {}
};//如果自定义构造函数,则初始化节点可直接赋值:ListNode* head=new ListNode(5);//如果使用默认的则不可直接赋值ListNode* head=new ListNode();head->val=5;


203.移除链表元素

建议: 本题最关键是要理解 虚拟头结点的使用技巧,这个对链表题目很重要。

一般代码题分析出怎么做了,就需要先看一下特殊情况,这个题是移除链表元素,那有可能移除头部的元素,这个情况是特殊的。

但是如果想要移动头指针所指向的元素,则需要将头指针后移,如果还需移除头结点则需要再移动,但这样与其余情况不形成统一,为了统一,我们设定一个虚拟头结点,用于需要删除头结点的情况。

当然也可以不设

这里只写设置虚拟头结点的代码:

/*** 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* removeElements(ListNode* head, int val) {ListNode* vhead=new ListNode(0);//虚拟头结点vhead->next=head;//遍历链表ListNode* p=vhead;//遍历指针while(p->next!=NULL){if(p->next->val==val){//清理移除的元素ListNode* tmp = p->next;p->next=p->next->next;delete tmp;}else{p=p->next;}}head=vhead->next;delete vhead;return head;}
};

707.设计链表

包含初始化、查询、插入、追加、删除操作,我们可以分别实现:

初始化:

LinkedNode* vhead; // 虚拟头节点int size;          // 链表大小MyLinkedList() {//初始化vhead=new LinkedNode(0);//直接初始化了size=0;};

在头部插入:
 

void addAtHead(int val) {//插到第一个元素之前LinkedNode* p = new LinkedNode(val);p->next = vhead->next;//这个为什么显示错误vhead->next=p;size++;}


在下标为index的前面插入

//将一个值为 val 的节点插入到链表中下标为 index 的节点之前void addAtIndex(int index, int val) {if (index > size || index < 0) {  return;}LinkedNode* p = new LinkedNode(val);LinkedNode* q=vhead;for(int i = 0; i < index; i++) {q = q->next;}p->next = q->next;q->next = p;size++;    }

在末尾插入

void addAtTail(int val) {//插到最后一个元素后LinkedNode* p = new LinkedNode(val);LinkedNode* q=vhead;while(q->next!=NULL){q=q->next;}q->next=p;size++;    }

查询下标为index的val

int get(int index) {if (index > size - 1 || index < 0) {return -1;}LinkedNode* p=vhead->next;//指针int c=0;while(p!=NULL){if(c++==index){return p->val;}p=p->next;}return -1;}


 删除下标为index前面的节点

void deleteAtIndex(int index) {if (index > size - 1 || index < 0) {return;}LinkedNode* q;q=vhead;// 需要找到要删除节点的前一个节点for(int i = 0; i < index; i++) {q = q->next;}LinkedNode* temp = q->next;q->next = q->next->next;delete temp;size--;}

单链表设计:

class MyLinkedList {
public://单链表struct LinkedNode {int val;LinkedNode* next;LinkedNode(int val):val(val), next(nullptr){}};LinkedNode* vhead; // 虚拟头节点int size;          // 链表大小MyLinkedList() {//初始化vhead=new LinkedNode(0);//直接初始化了size=0;};int get(int index) {if (index > size - 1 || index < 0) {return -1;}LinkedNode* p=vhead->next;//指针int c=0;while(p!=NULL){if(c++==index){return p->val;}p=p->next;}return -1;}void addAtHead(int val) {//插到第一个元素之前LinkedNode* p = new LinkedNode(val);p->next = vhead->next;//这个为什么显示错误vhead->next=p;size++;}void addAtTail(int val) {//插到最后一个元素后LinkedNode* p = new LinkedNode(val);LinkedNode* q=vhead;while(q->next!=NULL){q=q->next;}q->next=p;size++;}//将一个值为 val 的节点插入到链表中下标为 index 的节点之前void addAtIndex(int index, int val) {if (index > size || index < 0) {  return;}LinkedNode* p = new LinkedNode(val);LinkedNode* q=vhead;for(int i = 0; i < index; i++) {q = q->next;}p->next = q->next;q->next = p;size++;}void deleteAtIndex(int index) {if (index > size - 1 || index < 0) {return;}LinkedNode* q;q=vhead;// 需要找到要删除节点的前一个节点for(int i = 0; i < index; i++) {q = q->next;}LinkedNode* temp = q->next;q->next = q->next->next;delete temp;size--;}
};/*** 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);*/

206.反转链表

这题可以用双指针和递归

这里先写双指针方法,由于如果再创建链表会浪费空间,不如就在原链表上进行,而这种操作其实很想数组中的双指针,拿过来用就行。

双指针:

/*** 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* reverseList(ListNode* head) {ListNode* t;ListNode* pre;ListNode* cur;pre=NULL;cur=head;while(cur!=NULL){t=cur->next;cur->next=pre;pre=cur;cur=t;}return pre;}
};

递归法:

实际上用到了一个函数:

return reverse(cur, temp); 表示递归地反转链表,是递归反转链表算法的核心部分。

就是不断交换

class Solution {
public:ListNode* reverse(ListNode* pre,ListNode* cur){if(cur == NULL) return pre;ListNode* temp = cur->next;cur->next = pre;return reverse(cur,temp);}ListNode* reverseList(ListNode* head) {return reverse(NULL, head);}
};


文章转载自:

http://PD1JUwvf.nhrkL.cn
http://Ecpo1gtL.nhrkL.cn
http://x69V8US2.nhrkL.cn
http://J9ieokSt.nhrkL.cn
http://FgpSswwu.nhrkL.cn
http://AgHMkhHN.nhrkL.cn
http://DL0Mxz0X.nhrkL.cn
http://ODMLWGCh.nhrkL.cn
http://mcaf7OAL.nhrkL.cn
http://OfEY3997.nhrkL.cn
http://gPPUYhi9.nhrkL.cn
http://BxNPZ2Lm.nhrkL.cn
http://ISP8AGbr.nhrkL.cn
http://8oTXKWSn.nhrkL.cn
http://AOexBWJ4.nhrkL.cn
http://ldqvWmGv.nhrkL.cn
http://e81O2D1l.nhrkL.cn
http://duUsNxAY.nhrkL.cn
http://AP0ib5Oh.nhrkL.cn
http://eJ3fMx0q.nhrkL.cn
http://tLnyGiTi.nhrkL.cn
http://At4S2InN.nhrkL.cn
http://5fOZz376.nhrkL.cn
http://ocJhh01k.nhrkL.cn
http://g7MCxYyH.nhrkL.cn
http://BoTV4tlE.nhrkL.cn
http://li3sfGIQ.nhrkL.cn
http://4s5SBZhx.nhrkL.cn
http://975kUxK5.nhrkL.cn
http://MhfuFpdL.nhrkL.cn
http://www.dtcms.com/a/368392.html

相关文章:

  • 结合机器学习的Backtrader跨市场交易策略研究
  • 前端开发vscode插件 - live server
  • 码农的“必修课”:深度解析Rust的所有权系统(与C++内存模型对比)
  • 【Python基础】 17 Rust 与 Python 运算符对比学习笔记
  • 云手机可以息屏挂手游吗?
  • 会话管理巅峰对决:Spring Web中Cookie-Session、JWT、Spring Session + Redis深度秘籍
  • 腾讯云大模型训练平台
  • iPhone17全系优缺点分析,加持远程控制让你的手机更好用!
  • 数据泄露危机逼近:五款电脑加密软件为企业筑起安全防线
  • 阿里云vs腾讯云按量付费服务器
  • DocuAI深度测评:自动文档生成工具如何高效产出规范API文档与数据库表结构文档?
  • React JSX 语法讲解
  • 工厂办公环境如何实现一台服务器多人共享办公
  • 从 0 到 1 学 sed 与 awk:Linux 文本处理的两把 “瑞士军刀”
  • VNC连接服务器实现远程桌面-针对官方给的链接已经失效问题
  • 【Web】理解CSS媒体查询
  • 编写前端发布脚本
  • 无密码登录与设备信任:ABP + WebAuthn/FIDO2
  • 消息队列-ubutu22.04环境下安装
  • Vue3源码reactivity响应式篇之EffectScope
  • 从Java全栈到前端框架:一位程序员的实战之路
  • 【Java实战㉖】深入Java单元测试:JUnit 5实战指南
  • 【AI论文】Robix:一种面向机器人交互、推理与规划的统一模型
  • C++(Qt)软件调试---bug排查记录(36)
  • yolov8部署在一台无显卡的电脑上,实时性强方案
  • Alibaba Cloud Linux 3 安装Docker
  • SQL面试题及详细答案150道(61-80) --- 多表连接查询篇
  • 详细解读Docker
  • 【OJ】C++ vector类OJ题
  • 【数据库】MySQL 数据库创建存储过程及使用场景详解