代码随想录算法训练营day3|203.移除链表元素、707.设计链表、206.反转链表

第二章 链表part01

  •  链表理论基础 
  •  203.移除链表元素 
  •  707.设计链表 
  •  206.反转链表 

 链表理论基础 

建议:了解一下链接基础,以及链表和数组的区别 

文章链接:代码随想录

 203.移除链表元素  

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

题目链接:203. 移除链表元素 - 力扣(LeetCode)

文章讲解/视频讲解::代码随想录

 707.设计链表  

建议: 这是一道考察 链表综合操作的题目,不算容易,可以练一练 使用虚拟头结点

题目链接:707. 设计链表 - 力扣(LeetCode)

文章讲解/视频讲解:代码随想录

 206.反转链表 

题目链接:206. 反转链表 - 力扣(LeetCode)

文章讲解/视频讲解:代码随想录


c++代码示例如下O(n)

ListNode* removeElements(ListNode* head, int val) {while (head != NULL && head->val == val) {ListNode* tmp = head;head = head->next;delete tmp;}ListNode* cur = head;while (cur != NULL && cur->next != NULL) {if (cur->next->val == val) {ListNode* tmp = cur->next;cur->next = cur->next->next;delete tmp;}else {cur = cur->next;}}return head;
}

设置一个虚拟头结点再进行移除节点操作

ListNode* removeElements(ListNode* head, int val) {ListNode* dummyHead = new ListNode(0);dummyHead->next = head;ListNode* cur = dummyHead;while (cur->next != NULL) {if (cur->next->val == val) {ListNode* tmp = cur->next;cur->next = cur->next->next;delete tmp;}else {cur = cur->next;}}head = dummyHead->next;delete dummyHead;return head;
}

这个例子中ListNode(0)源于链表结构体定义中的构造函数。

ListNode(int x) : val(x),next(NULL) {}

让我们逐一解析这段代码:

  1. ListNode (int x): 这是ListNode类的构造函数的声明。它接受一个整数参数x
  2. :val(x), next(NULL): 这是初始化列表。它用于初始化类的成员变量。在这里,val成员变量被初始化为x,而next成员变量被初始化为NULL
  3. { }: 这是构造函数的主体。在这里它是空的,因为所有的初始化都在初始化列表中完成了。

总的来说,当你创建一个新的ListNode对象并传递一个整数给它时,这个构造函数将确保该节点的值被设置为该整数,并且该节点没有指向任何下一个节点(因为next被初始化为NULL)。

注意:如果不定义构造函数使用默认构造函数的话,在初始化的时候不能直接给变量赋值!

c++代码示例如下

class MyLinkedList {
public:struct LinkedNode {int val;LinkedNode* next;LinkedNode(int val) :val(val), next(NULL) {}};MyLinkedList() {dummyHead = new LinkedNode(0);size = 0;}int get(int index) {if (index > (size - 1)|| index < 0){return -1;}LinkedNode* cur = dummyHead->next;while (index--) {cur = cur->next;}return cur->val;}void addAtHead(int val) {LinkedNode* newNode = new LinkedNode(val);newNode->next = dummyHead->next;dummyHead->next = newNode;size++;}void addAtTail(int val) {LinkedNode* newNode = new LinkedNode(val);LinkedNode* cur = dummyHead;while (cur->next != NULL) {cur = cur->next;}cur->next = newNode;size++;}void addAtIndex(int index, int val) {if (index > size) return;if (index < 0) index = 0;LinkedNode* newNode = new LinkedNode(val);LinkedNode* cur = dummyHead;while (index--) {cur = cur->next;}newNode->next = cur->next;cur->next = newNode;size++;}void deleteAtIndex(int index) {if (index >= size || index < 0) {return;}LinkedNode* cur = dummyHead;while (index--) {cur = cur->next;}LinkedNode* tmp = cur->next;cur->next = cur->next->next;delete tmp;tmp = NULL;size--;}
private:int size;LinkedNode* dummyHead;
};

c语言代码示例如下

typedef struct MyLinkedList {int val;struct MyLinkedList* next;
}MyLinkedList;
MyLinkedList* myLinkedListCreate() {MyLinkedList* head = (MyLinkedList*)malloc(sizeof(MyLinkedList));head->next = NULL;return head;
}
int myLinkedListGet(MyLinkedList* obj, int index) {MyLinkedList* cur = obj->next;for (int i = 0; cur != NULL; i++) {if (i == index) {return cur->val;}else {cur = cur->next;}}return -1;
}
void myLinkedListAddAtHead(MyLinkedList* obj, int val) {MyLinkedList* nhead = (MyLinkedList*)malloc(sizeof(MyLinkedList));nhead->val = val;nhead->next = obj->next;obj->next = nhead;
}
void myLinkedListAddAtTail(MyLinkedList* obj, int val) {MyLinkedList* cur = obj;while (cur->next != NULL) {cur = cur->next;}MyLinkedList* ntail = (MyLinkedList*)malloc(sizeof(MyLinkedList));ntail->val = val;ntail->next = NULL;cur->next = ntail;
}
void myLinkedListAddAtIndex(MyLinkedList* obj,int index,int val) {if (index == 0) {myLinkedListAddAtHead(obj, val);return;}MyLinkedList* cur = obj->next;for (int i = 1; cur != NULL; i++){if (i == index) {MyLinkedList* newNode = (MyLinkedList*)malloc(sizeof(MyLinkedList));newNode->val = val;newNode->next = cur->next;cur->next = newNode;return;}else {cur = cur->next;}}
}
void myLinkedListDeleteAtIndex(MyLinkedList* obj, int index) {if (index == 0) {MyLinkedList* tmp = obj->next;if (tmp != NULL) {obj->next = tmp->next;free(tmp);}return;}MyLinkedList* cur = obj->next;for (int i = 1; cur != NULL && cur->next != NULL; i++) {if (i == index) {MyLinkedList* tmp = cur->next;if (tmp != NULL) {cur->next = tmp->next;free(tmp);}return;}else {cur = cur->next;}}
}
void myLinkedListFree(MyLinkedList* obj) {while (obj != NULL) {MyLinkedList* tmp = obj;obj = obj->next;free(tmp);}
}

        已知头结点,使用双指针法一个节点一个节点的处理:

定义一个cur指针(head),pre指针(NULL),定义一个临时变量tmp把cur->next的内容拿出来,然后把pre指针放进去,就完成了节点的反转。更新pre指针(cur),cur指针(tmp)。循环遍历完链表就完成整体的反转。循环结束时,cur一定指向最后一个节点的->next==NULL,pre一定指向最后一个节点。返回pre

c++代码示例如下O(n)

ListNode* reverseList(ListNode* head) {ListNode* tmp;ListNode* cur = head;ListNode* pre = NULL;while (cur) {tmp = cur->next;cur->next = pre;pre = cur;cur = tmp;}return pre;
}

还可以用递归实现,能够迭代就一定可以递归!

ListNode* reverse(ListNode* pre, ListNode* cur) {if (cur == NULL) {return pre;}ListNode* tmp = cur->next;cur->next = pre;return reverse(cur, tmp);
}

这个代码实现逻辑和双指针实现逻辑一模一样,实质上都是从前往后反转指针指向,其实还可以从后往前反转指针。(这个方法还不懂)

ListNode* reverseList(ListNode* head) {if (head == NULL) return NULL;if (head->next == NULL) return head;ListNode* last = reverseList(head->next);head->next->next = head;head->next = NULL;return last;
}

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

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

相关文章

详解Vue3中的常见的监听事件submit、mouseenter和mouseleave

本文主要介绍Vue3中的常见的监听事件submit、mouseenter和mouseleave。 目录 一、submit点击事件二、mouseenter事件三、mouseleave点击事件四、mouseenter和mouseleave的注意事项 在Vue3中&#xff0c;常见的监听事件有以下几种&#xff1a; 一、submit点击事件 我们在提交表…

win上使用wireshark 抓包 | 安装、实战抓包、筛选规则

先随便讲两句吧 win 上抓包&#xff0c;使用wireshark 直接运行&#xff0c;通过选定网卡、配置筛选规则 相比&#xff0c;在linux 上抓包&#xff0c;直接使用命令 tcpdump 再添加筛选规则 就可以 好像wireshark的一个插件不维护&#xff0c;导致需要重新安装插件&#xff0c;…

STM32CubeMX教程8 TIM 通用定时器 - 输出比较

目录 1、准备材料 2、实验目标 3、实验流程 3.0、前提知识 3.1、CubeMX相关配置 3.1.1、时钟树配置 3.1.2、外设参数配置 3.1.3、外设中断配置 3.2、生成代码 3.2.1、外设初始化函数调用流程 3.2.2、外设中断函数调用流程 3.2.3、添加其他必要代码 4、常用函数 5…

GIT提交、回滚等基本操作记录

1、add文件时warning: LF will be replaced by CRLF in .idea/workspace.xml. 原因&#xff1a;windows中的换行符为 CRLF&#xff0c; 而在Linux下的换行符为LF&#xff0c;所以在执行add . 时会出现以下提示 解决&#xff1a;git config core.autocrlf false 2、GIT命令&…

Modbus,DNP3的理解

Modbus&#xff0c;DNP3的理解 目录概述需求&#xff1a; 设计思路实现思路分析1.概念理解3.区别 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better result,wait for…

Unity中Shader裁剪空间推导(在Shader中使用)

文章目录 前言一、在Shader中使用转化矩阵1、在顶点着色器中定义转化矩阵2、用 UNITY_NEAR_CLIP_VALUE 区分平台矩阵3、定义一个枚举用于区分当前是处于什么相机 二、我们在DirectX平台下&#xff0c;看看效果1、正交相机下2、透视相机下3、最终代码 前言 在上一篇文章中&…

思维训练-怎样设计一个MQ

架构师需要做各种设计&#xff0c;要不断地提高自己的设计能力。这有没有方法可以训练呢&#xff1f;有的&#xff0c;就是看到什么、想到什么&#xff0c;就假设对面坐着产品经理&#xff0c;一起讨论怎么把它设计出来。比如怎样设计一个MQ 我&#xff1a;首先我确认一下需求。…

Java设计模式-外观模式

目录 一、影院管理项目 二、外观模式 &#xff08;一&#xff09;基本介绍 &#xff08;二&#xff09;原理类图 &#xff08;三&#xff09;解决影院管理 &#xff08;四&#xff09;注意事项和细节 &#xff08;五&#xff09;外观模式在MyBatis框架应用的源码分析 一…

计算机毕业设计------ssm茶叶溯源系统

项目介绍 茶叶溯源系统&#xff0c;分为前台与后台。普通用户可在前台通过18位的编码查询茶叶的出售历史。 后台分为两种角色&#xff0c;管理员与经销商&#xff1b; 管理员主要功能包括&#xff1a; 主界面&#xff1b; 管理员管理&#xff1a;管理员列表、添加管理员&am…

AIGC系统ChatGPT系统源码,Midjourney绘画,GPT语音对话+ChatFile文档对话总结+DALL-E3文生图+思维导图一站式解决方案

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作Ch…

基于Java网上点餐系统设计与实现

博主介绍&#xff1a; ✌至今服务客户已经1000、专注于Java技术领域、项目定制、技术答疑、开发工具、毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅 &#x1f447;&#x1f3fb; 不然下次找不到 Java项目精品实…

人工智能工程师的前景怎么样

人工智能是未来的发展趋势&#xff0c;因此&#xff0c;人工智能工程师也将成为就业爆款。人工智能工程师负责创建和开发自动化系统、算法和机器学习模型&#xff0c;以实现自主决策和任务执行。由于人工智能在可穿戴设备、家庭自动化、智能城市和自动驾驶等领域都有广泛应用&a…