链表经典OJ题(链表回文结构,链表带环,链表的深拷贝)

目录

前言

1.反转一个单链表。 

2.   给定一个带有头结点 head 的非空单链表,返回链表的中间结点。

3.链表的回文结构。

 4.链表带环问题(*****)

4.1是否带环

4.2 入环的节点

5.随机链表的复制(链表的深拷贝)


前言

        前面我们学习了链表,现在我们来手撕几道经典链表OJ题目吧!!!


1.反转一个单链表。 

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

题解:

        在这一题,我们定义了三个指针变量,首先让prev指向NULL,prev的作用是保存cur的前面的一个节点,next是保存cur后面的节点。

        每一次循环迭代,都让cur指向前面的节点,也就是指向prev;

        再让prev去到cur的位置,cur去到next位置,最后再让next去到cur->next的位置,这样就完成了一次循环迭代。直到cur为NULL;
 

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

        这样就通过了!

      


2.   给定一个带有头结点 head 的非空单链表,返回链表的中间结点。

题目链接:876. 链表的中间结点 - 力扣(LeetCode)


 

题解:

        这题思想其实非常简单,既然让返回中间节点,那么我们就定义两个指针,fast和slow,让fast走两步,slow走一步,这样fast走完全程之后,slow就只走了一半。

        需要注意的是,节点总数为奇数时,fast走到最后一个节点就结束,而节点总数为偶数时,fast节点就要走到NULL。因此结束条件就要写成(fast&&fast->next)。

struct ListNode* middleNode(struct ListNode* head){struct ListNode* slow = head,*fast = head;while(fast&&fast->next){slow = slow->next;fast = fast->next->next;}return slow;
}

3.链表的回文结构。

题目链接:链表的回文结构_牛客题霸_牛客网 (nowcoder.com)


 题解:

        这一题看似复杂,实际不难。我们只需要找到中间节点,然后从中间节点反转链表 ,再分别从两个头开始遍历,若每个节点都相等,则为回文结构。

        如果是奇数个,两条链表节点数量会不会不想等呢?

        不会!因为A链表的最后一个并没有与B链表的最后一个节点断开,所以两链表有一个 公共节点,因此在奇数个节点下,两链表节点个数也相同,结束条件显而易见为:(head&&rhead)。

class PalindromeList {
public:
struct ListNode* reverseList(struct ListNode* head) {//反转链表struct ListNode*prv = NULL;struct ListNode*cur = head;struct ListNode*n =head;while(n){n = cur->next;cur->next = prv;prv =cur;cur = n;}return prv;
}
struct ListNode* middleNode(struct ListNode* head){//找中间节点struct ListNode* slow = head,*fast = head;while(fast&&fast->next){slow = slow->next;fast = fast->next->next;}return slow;
}bool chkPalindrome(ListNode* A) {ListNode* mid = middleNode(A);ListNode*rhead = reverseList(mid);while(A&&rhead){if(A->val!=rhead->val)return false;A=A->next;rhead=rhead->next;}return true;}    
};


 4.链表带环问题(*****)

        链表带环问题是链表中非常重要的一类问题,在企业面试中也会经常遇到。此类问题有两种,第一种是判断链表是否带环,第二种是判断链表开始入环的节点是哪个。


4.1是否带环

题目链接:141. 环形链表 - 力扣(LeetCode)

题解:我们不禁思索,该如何判断链表是否带环呢?

        在这里我们可以定义两个指针fast和slow,让fast先走,如果到最后还能与slow相遇,那就证明该链表是带环的。在此就引出了一个问题,fast要比slow快多少?

        1.slow一次走一步fast一次走两步一定会相遇吗?

        答案是一定会相遇,因为fast和slow的距离每次都缩减1,到最后一定会减到0。

        2.slow一次走一步fast一次走三步一定会相遇吗?

        答案是不一定,如果N为偶数,fast和slow的距离每次都缩减2,最后一定会减到0。如果为奇数,最后会减到-1,这样就又开始新一轮的追击了,而且永远不会相遇。

        3.slow一次走n步fast一次走m步一定会相遇吗?(m>n>1)

        最后我们得到2L = n*C-N最后一定得到的是一个奇数,所以最后一定能追上。

bool hasCycle(struct ListNode *head) {struct ListNode* fast = head,*slow =head;while(fast&&fast->next){fast =fast->next->next;slow =slow ->next;if(fast ==slow)return fast;}return NULL;
}

4.2 入环的节点

题目链接:142. 环形链表 II - 力扣(LeetCode) 、

题解:这一题与上一题是不一样的,这一题是要找到入环的节点,从哪个节点开始入环,这题难度相较于上一题显然是上升了。

        假设,fast和slow在meet点相遇,那么slow就走了(L+X)的距离,fast就走了(L+X+n*C)的距离,最后由图上等式可得,L=n*C-X,那也就是说,如果相同速度的指针,一个从相遇点开始走,另一个从入口点开始走,他们到入口与点的距离是一样的,所以一定会在入口点相遇。

        因此本题思路就出来了:1.找到相遇点 2.让相同速度的指针,一个从相遇点开始走,另一个从入口点开始走。最终就一定会相遇。

struct ListNode *detectCycle(struct ListNode *head) {struct ListNode *slow = head,*fast =head;while(fast&&fast->next){slow = slow->next;fast= fast->next->next;if(slow == fast){struct ListNode* meet= slow;while(head!=meet){head = head->next;meet =meet->next;}return meet;}}return NULL;
}

5.随机链表的复制(链表的深拷贝)

题目链接:138. 随机链表的复制 - 力扣(LeetCode)

题解:链表的深拷贝,是链表中较难的问题,但如果把思路理清,问题也就迎刃而解了。

        我们的第一思路可能就是将每个节点的信息先拷贝下来,然后我们来处理random的指向的时候,可能就是用嵌套循环将每个节点的random进行比较,来确定指向,这样一来就造成时间复杂度到达O(N^2)了,这就不符合题目要求了。

        那么我这里就提供一种可行的思路:

                1.拷贝的节点都插入在原来节点的后面(如图)

                2.处理random的指向

        我们可以清楚的看到,原节点的下一个节点就是我们所拷贝的节点,那么让本来指向原节点random,指向原节点的下一个是不是就可以让拷贝节点的random完成正确的指向,这就解决了然random指向的问题了。如图(我们已经得到所有的拷贝节点了。)

                3.copy的节点一个一个的解下来尾插就可以得到我们想要的深拷贝出来的链表了。

完整代码:

truct Node* copyRandomList(struct Node* head) {struct Node* cur =head;while(cur){struct Node*copy= (struct Node*)malloc(sizeof(struct Node));copy->val =cur->val;copy->next = cur->next;cur->next = copy;cur=cur->next->next;}cur =head;while(cur){struct Node*copy= cur->next;if(cur->random ==NULL)copy->random =NULL;elsecopy->random = cur->random->next;cur = cur->next->next; }struct Node* newhead = NULL,*fail=NULL;cur =head;while(cur){struct Node*copy = cur->next;struct Node*next =copy->next;if(newhead==NULL){newhead = fail = copy;}else{fail->next = copy;fail=fail->next;}cur->next = next;cur = next;}return newhead;
}

这里都是链表比较经典的题目,希望对你有所帮助!!!

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

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

相关文章

Redis的三种特殊数据类型

文章目录 一、Redis geospatial 地理位置二、Redis Hyperloglog 基数统计的算法三、Redis Bitmaps 位存储(0、1)总结 一、Redis geospatial 地理位置 1.geoadd:将指定的地理空间位置(纬度、经度、名称)添加到指定的ke…

人工智能-卷积神经网络(LeNet)

为了能够应用softmax回归和多层感知机,我们首先将每个大小为\(28\times28\)的图像展平为一个784维的固定长度的一维向量,然后用全连接层对其进行处理。 而现在,我们已经掌握了卷积层的处理方法,我们可以在图像中保留空间结构。 同…

Dubbo从入门到上天系列第五篇:Dubbo3与JDK17不兼容问题展示

文章目录 一:JDK 与 Dubbo版本对应问题说明 1:问题1 2:问题2 二:Spring与JDK版本对应关系 1:对应关系详图 2:JDK与Major对应关系图 大神链接:作者有幸结识技术大神孙哥为好友&#xff0c…

[ Linux Busybox ] nandwrite 命令解析

文章目录 相关结构体nandwrite 函数实现nandwrite 实现流程图 文件路径:busybox-1.20.2/miscutils/nandwrite.c 相关结构体 MTD 相关信息结构体 struct mtd_info_user {__u8 type; // MTD 设备类型__u32 flags; // MTD设备属性标志__u32…

基于STM32控制直流电机加减速正反转仿真设计

**单片机设计介绍,基于STM32控制直流电机加减速正反转仿真设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 本设计由STM32F103、L298N电机驱动电路、按键电路组成。通过按键可以控制电机,正转、反转、加…

商越科技:渗透测试保障平台安全,推动线上采购高效运转

商越科技是数字化采购解决方案提供商,在同赛道企业中始终保持前列。商越科技通过自主研发的智能采购中台、SaaS应用及运营服务等为企业搭建专属的互联网采购平台,帮助企业实现采购数字化以及智能化转型,提高工作效率、降低采购成本。 打造数字…

Linux基础开发工具之调试器gdb

文章目录 1.编译成的可调试的debug版本1.1gcc test.c -o testdebug -g1.2readelf -S testdebug | grep -i debug 2.调试指令2.0quit退出2.1list/l/l 数字: 显示代码2.2run/r运行2.3断点相关1. break num/b num: 设置2. info b: 查看3. d index: 删除4. n: F10逐过程5. p 变量名…

Java必刷入门递归题×5(内附详细递归解析图)

目录 1.求N的阶乘 2.求12...N的和 3.顺序打印数字的每一位 4.求数字的每一位之和 5.求斐波拉契数列 1.求N的阶乘 (1)解析题目意思 比如求5的阶乘,符号表示就是5!;所以5!5*4*3*2*1我们下面使用简单的…

SSM图书管理系统开发mysql数据库web结构java编程计算机网页源码eclipse项目

一、源码特点 SSM 图书管理系统是一套完善的信息系统,结合springboot框架和bootstrap完成本系统,对理解JSP java编程开发语言有帮助系统采用SSM框架(MVC模式开发),系统具有完整的源代码和 数据库,系统主要…

Linux-Docker的基础命令和部署code-server

1.安装docker 1.安装需要的安装包 yum install -y yum-utils2.设置镜像仓库 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo3.安装docker yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin do…

多彩的树 -----题解(状压dp + 容斥原理)

目录 多彩的树 题目描述 输入描述: 输出描述: 输入 输出 思路解析: 代码实现: 多彩的树 时间限制:C/C 5秒,其他语言10秒 空间限制:C/C 262144K,其他语言524288K 64bit IO Format: %lld 题目描述 …

【Springboot】Vue3-Springboot引入JWT实现登录校验以及常见的错误解决方案

文章目录 前言一、JWT简单介绍二、token校验设计思路三、使用步骤Springboot部署JWT引入依赖:创建登录实体类后端:LoginController.java路由守卫函数 四、问题 前言 项目版本: 后端: Springboot 2.7、 Mybatis-plus、Maven 3.8.1…

C/C++轻量级并发TCP服务器框架Zinx-游戏服务器开发004:游戏核心消息处理 - 玩家类的实现

文章目录 0 代码仓库1 需求2 AOI设计2.1 AOI算法简介2.2 AOI数据结构及实现2.2.1 玩家2.2.2 网格对象2.2.3 游戏世界矩形2.2.4 获取周围玩家的实现2.2.5 代码测试 2.3 GameRole结合AOI创建玩家2.3.1 创建游戏世界全局对象-GameRole继承AOIWorld的Player2.3.2 把玩家到游戏世界的…

1.docker linux离线环境安装 20.1.0.12

目录 概述下载解压docker 卸载docker 安装检查安装环境常用命令结束 概述 docker离线环境安装 20.1.0.12 , centos 7.x 下载 安装包下载 解压 [roothadoop01 soft]# unzip docker_20_1_0_12.zip [roothadoop01 soft]# cd docker_20_1_0_12 [roothadoop01 docker_20_1_0_1…

数据结构:树的基本概念(二叉树,定义性质,存储结构)

目录 1.树1.基本概念1.空树2.非空树 2.基本术语1.结点之间的关系描述2.结点、树的属性描述3.有序树、无序树4.森林 3.树的常考性质 2.二叉树1.基本概念2.特殊二叉树1.满二叉树2.完全二叉树3.二叉排序树4.平衡二叉树 3.常考性质4.二叉树的存储结构1.顺序存储2.链式存储 1.树 1.…

亚马逊云AI应用科技创新下的Amazon SageMaker使用教程

目录 Amazon SageMaker简介 Amazon SageMaker在控制台的使用 模型的各项参数 pytorch训练绘图部分代码 Amazon SageMaker简介 亚马逊SageMaker是一种完全托管的机器学习服务。借助 SageMaker,数据科学家和开发人员可以快速、轻松地构建和训练机器学习模型&#…

ARM寄存器及功能介绍/R0-R15寄存器

1、ARM 寄存器组介绍 ARM 处理器一般共有 37 个寄存器,其中包括: (1) 31 个通用寄存器,包括 PC(程序计数器)在内,都是 32 位的寄存器。 (2) 6 个状态寄存器…

服务号如何升级订阅号

服务号和订阅号有什么区别?服务号转为订阅号有哪些作用?首先我们要知道服务号和订阅号有什么区别。服务号侧重于对用户进行服务,每月可推送4次,每次最多8篇文章,发送的消息直接显示在好友列表中。订阅号更侧重于信息传…

通信信道:无线信道中衰落的类型和分类

通信信道:无线信道中衰落的类型和分类 在进行通信系统仿真时,简单的情况下选择AWGN信道,但是AWGN信道和真是通信中的信道相差甚远,所以需要仿真各种其他类型的信道,为了更清楚理解仿真信道的特点,首先回顾…

linux安装并配置git连接github

git安装 sudo apt-get install git git信息配置 git config --global uer.name "yourname" git config --global user.email "youremail" 其中,yourname是你在github上配置的用户名,youremail是你在github上设置的邮箱 查看git…