代码随想录训练营day 4|链表基础理论,移除链表元素,设计链表,反转链表
链表理论基础
链表是一种由指针串联在一起的线性结构,每一个节点都由一个数据域和一个指针域组成。
链表的类型有:单链表、双链表、循环链表。
链表的存储方式:在内存中不连续分布。
链表的定义很多人因为不重视而忽略,手写就显得很重要,如下所示:
// 单链表
struct ListNode {
int val; // 节点上存储的元素
ListNode *next; // 指向下一个节点的指针
ListNode(int x) : val(x), next(NULL) {} // 节点的构造函数
};
203.移除链表元素
题目链接:203.移除链表元素
题目描述:题意:删除链表中等于给定值 val 的所有节点。
示例 1:
输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]
思路
本题其实有两种代码解法,
一是:直接使用原来的链表来进行删除操作
二是:设置一个虚拟的头结点再进行删除操作
这里就不用第一种方案,因为第二种方便且实用。
代码如下(c++):
class Solution {
public:
ListNode* removeElements(ListNode* head, int val){
dummy head = new();、、设置一个虚拟头结点
dummy head->next = head;//让虚拟头节点指向了头节点
cur = dummy head;
//实际要删除的是cur->next,才能让cur指向删除后的元素
while(cur->next != Null){
if(cur->next->val == target){
cur->next = cur->next->next;//完成删除操作
else//没有找到要删除的目标值
cur = cur->next;//继续往下遍历
}
return dummy head->next;//这里要返回的是虚拟头节点的下一个
//即:新链表的头节点,原head可能已经删除
//头节点的指针是不能改动的,遍历链表的时候要定义一个
//临时的指针cur
}
}
707.设计链表
题目链接:707.设计链表
题目描述:在链表类中实现这些功能:
获取链表第index个节点的数值 //get(index)
在链表的最前面插入一个节点 //addAtHead(val)
在链表的最后面插入一个节点 //addAtTail(val)
在链表第index个节点前面插入一个节点 //addAtIndex(index,val)
删除链表的第index个节点 //deleteAtIndex(index)
思路
可以说这五个接口,已经覆盖了链表的常见操作,是练习链表操作非常好的一道题目。
直接上代码:
class MyLinkedList {
public:
// 定义链表节点结构体
struct LinkedNode {
int val;
LinkedNode* next;
LinkedNode(int val):val(val), next(nullptr){}
};
int get(int n) {
if (n > (_size - 1) || n < 0) {
return -1;
}//这里n就是第n个节点的n,若n<0||n>size - 1,则n不合法
/*遍历链表的时候,要定义一个cur(临时)指针来遍历而不是直接操作头指针
因为操作完链表后,我们要返回头结点,如果上来就操作头节点那么他的值都改了,不得行*/
cur = dummyhead->next;//让cur直接指向当前节点,即第零号节点(head节点)
while(n){
cur = cur->next;
n--;
}
return cur->val;//想象直接特殊情况 第0个节点
}
// 在链表最前面插入一个节点,插入完成后,新插入的节点为链表的新的头结点
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);//tongshang
LinkedNode* cur = _dummyHead;//
while(cur->next != nullptr){// 当cur节点的后一个节点为空,循环终止
cur = cur->next;
}
cur->next = newNode;//直接指向新节点,即加入
_size++;
}
//在第n个节点前插入节点......
/*第n个节点其实就是cur->next*/
newNode = new LinkedNode(val);
LinkedNode* cur = _dummyHead;
while(n--) {
cur = cur->next;
}
newNode->next = cur->next;
cur->next = newNode;
_size++;
// 删除第index个节点,如果index 大于等于链表的长度,直接return,注意index是从0开始的
void deleteAtIndex(int index) {
if (index >= _size || index < 0) {
return;
}
LinkedNode* cur = _dummyHead;
while(n--) {
cur = cur ->next;
}
cur->next = cur->next->next;
size--;
206.反转链表
题目链接:206.反转链表
题目描述:题意:反转一个单链表。
示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL
主要思路
改变链表的next指针指向即可实现链表的反转。
首先定义一个cur指针,指向头结点,再定义一个pre指针,初始化为null。
然后就要开始反转了,首先要把 cur->next 节点用tmp指针保存一下,也就是保存一下这个节点。
为什么要保存一下这个节点呢,因为接下来要改变 cur->next 的指向了,将cur->next 指向pre ,此时已经反转了第一个节点了。
接下来,就是循环走如下代码逻辑了,继续移动pre和cur指针。
最后,cur 指针已经指向了null,循环结束,链表也反转完毕了。 此时我们return pre指针就可以了,pre指针就指向了新的头结点。
代码实现
双指针法:
Copy
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* temp; // 保存cur的下一个节点
ListNode* cur = head;
ListNode* pre = NULL;
while(cur) {
temp = cur->next; // 保存一下 cur的下一个节点,因为接下来要改变cur->next
cur->next = pre; // 翻转操作
// 更新pre 和 cur指针
pre = cur;
cur = temp;
}
return pre;
}
};
总结
反转链表下次手撕一遍,链表这节有点基础,尽快拿下。
代码随想录训练营day 4|链表基础理论,移除链表元素,设计链表,反转链表的更多相关文章
- 【剑指Offer面试题】 九度OJ1518:反转链表
与其非常快写出一段漏洞百出的代码,倒不如细致分析再写出鲁棒的代码. 提前想好測试用例(输入非空等等)进行測试改动代码. 题目链接地址: http://ac.jobdu.com/problem.php? ...
- 力扣 - 92. 反转链表II
目录 题目 思路1(迭代) 代码 复杂度分析 思路2(递归) 代码 复杂度分析 题目 92. 反转链表 II 思路1(迭代) 将反转链表分成3个部分:前一段未反转的部分.待反转链表部分.后一段未反转部 ...
- 【Leetcode链表】反转链表 II(92)
题目 反转从位置 m 到 n 的链表.请使用一趟扫描完成反转. 说明: 1 ≤ m ≤ n ≤ 链表长度. 示例: 输入: 1->2->3->4->5->NULL, m ...
- 代码随想录第十三天 | 150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素
第一题150. 逆波兰表达式求值 根据 逆波兰表示法,求表达式的值. 有效的算符包括 +.-.*./ .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 注意 两个整数之间的除法只保留整数部分. ...
- 剑指offer-第三章高质量代码(反转链表)
题目:定义一个函数,输入一个链表的头节点,反转该链表并输出反转链表的头节点. 思路:对一个链表反转需要三个指针操作来保证链表在反转的过程中保证不断链,给链表一个行动指针pNode,对pNode指向的节 ...
- 代码随想录第八天 |344.反转字符串 、541. 反转字符串II、剑指Offer 05.替换空格 、151.翻转字符串里的单词 、剑指Offer58-II.左旋转字符串
第一题344.反转字符串 编写一个函数,其作用是将输入的字符串反转过来.输入字符串以字符数组 s 的形式给出. 不要给另外的数组分配额外的空间,你必须原地修改输入数组.使用 O(1) 的额外空间解决这 ...
- python经典面试算法题1.2:如何从无序链表中移除重复项
本题目摘自<Python程序员面试算法宝典>,我会每天做一道这本书上的题目,并分享出来,统一放在我博客内,收集在一个分类中. 1.2 如何实现链表的逆序 [蚂蚁金服面试题] 难度系数:⭐⭐ ...
- HTML5新增及移除的元素
HTML经过10多年的发展,其元素经历了废弃与不断重新定义的过程.为了更好的处理现在的互联网应用,HTML5新增了图形绘制.多媒体播放.页面结构.应用程序存储.网络工作等新元素.http://hove ...
- 剑指Offer面试题:15.反转链表
一.题目:反转链表 题目:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点. 链表结点定义如下,这里使用的是C#描述: public class Node { public in ...
- 剑指Offer 反转链表
题目描述 输入一个链表,反转链表后,输出链表的所有元素. 思路: 法1:用栈,压栈出栈 法2:头插法(有递归非递归2中) AC代码: /* struct ListNode { int va ...
随机推荐
- 面对集中式缓存实现上的挑战,Redis交出的是何种答卷?聊聊Redis在分布式方面的能力设计
大家好,又见面了. 本文是笔者作为掘金技术社区签约作者的身份输出的缓存专栏系列内容,将会通过系列专题,讲清楚缓存的方方面面.如果感兴趣,欢迎关注以获取后续更新. 在本专栏前面的文章中,我们介绍了各种本 ...
- Java学习笔记:2022年1月11日
Java学习笔记:2022年1月11日 摘要:这篇笔记主要讲解了一些数据在计算机中的存在方式相关的知识点,并由此延伸出了数据在计算机中的操作以及一些数据结构的知识. @ 目录 Java学习笔记:2 ...
- BC3-牛牛学说话之-整数
题目描述 牛牛刚刚出生,嗷嗷待哺,一开始他只能学说简单的数字,你跟他说一个整数,他立刻就能学会.输入一个整数,输出这个整数. 输入描述 输入一个整数,范围在32位有符号整数范围内 输出描述 输出这个整 ...
- echarts图例过多,折线过多颜色不知道怎么分配怎么办??优化如下
优化一:很简单,echarts自身支持legend图例分页,加了分页就优化了图例过多情况. legend['type']: 'scroll', // 添加这一行代码即可实现图例分页功能 option ...
- 《深入理解Java虚拟机》第三章读书笔记(一)——垃圾回收算法
参考书籍<深入理解java虚拟机>周志明著 系列文章目录和关于我 本文主要介绍垃圾回收理论知识 1.jvm哪些区域需要进行垃圾回收 虚拟机栈,本地方法栈,程序计数器都是线程私有的,随线程而 ...
- hashlib加密模块及subprocess远程命令模块
hashlib加密模块及subprocess远程命令模块 一.hashlib加密模块 1.加密模块简介 1.加密模块简介 将明文数据进行加密处理,转变为密文数据再存储或者传输,这样的安全机制可以让用户 ...
- thinkphp无法访问man.php/index/login
配置半天.user.ini,权限问题解决了,但是还是访问不了后台登陆界面(链接:域名/man.php/index/login),后来发现是伪静态thinkphp没设置好,设置好后重启nginx就好啦
- sync.Once 使用及解析
目录 前言 1. sync.Once 简介 2. sync.Once 源码解析 2.1 为什么 done 作为第一个字段 2.2 Do 方法的实现细节 2.3 其他重要细节 3. sync.Once ...
- 1.2.HBuilder软件与uniapp文件介绍
uni-app官网地址 下载HBuilder 教程
- 视觉十四讲:第七讲_2D-2D:对极几何估计姿态
1.对极几何 从2张图片中,得到若干个配对好的2d特征点,就可以运用对极几何来恢复出两帧之间的运动. 设P的空间坐标为: \(P=[X,Y,Z]^{T}\) 两个像素点\(p_{1},p_{2}\)的 ...