LeetCode/NowCoder-链表经典算法OJ练习4

·人的才华就如海绵的水,没有外力的挤压,它是绝对流不出来的。流出来后,海绵才能吸收新的源泉。💓💓💓

目录

说在前面

题目一:环形链表

 题目二:环形链表 II

题目三:随机链表的复制

SUMUP结尾


说在前面

 dear朋友们大家好!💖💖💖我们又见面了,接着上一个篇目,我们接着继续练习有关链表的面试题、OJ题,希望大家和我一起学习,共同进步~

 👇👇👇

友友们!🎉🎉🎉点击这里进入力扣leetcode学习🎉🎉🎉


​以下是leetcode题库界面:

 👇👇👇

🎉🎉🎉点击这里进入牛客网NowCoder刷题学习🎉🎉🎉
​以下是NowCoder题库界面:

​​

 ​​

题目一:环形链表

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

题目描述:

题目分析:

 思路:快慢指针法。创建快慢指针fast、slow,快指针每次走两步,慢指针每次走一步,如果fast追击上slow(即fast最终等于slow),则链表带环,否则不带环。

代码如下:

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/typedef struct ListNode ListNode;
bool hasCycle(struct ListNode *head) {ListNode* slow = head, *fast = head;//创建快慢指针fast、slowwhile(fast && fast->next)//fast走两步,slow走一步{slow = slow->next;fast = fast->next->next;if(slow == fast)//fast追击上slow,则链表带环return true;}return false;
}

思考下列问题:

 当然,虽然这道题比较简单,但是有些问题我们还是需要搞清楚:

1、为什么一定会相遇,有没有可能会错过,永远追不上?请证明。

答:不会错过。

证明:

假设slow进环时,fast和slow之间的距离为d,那么在fast追击slow的过程中,距离变化为d、d-1、d-2、d-3、...、2、1、0,最终会减到0。当距离为0时,fast追上slow,也就是每追击一次距离d减小1,所以一定能追上。

2、slow一次走1步,fast走3步可以吗?4步、5步、n步呢?请证明。

答:不稳定,有可能很久都追不上。

证明:

我们先考虑slow走1步,fast走3步的情况,剩下的都是如法炮制。同样假设fast和slow之间的距离为d,那么在fast追击slow的过程中,距离变化为d、d-2、d-4、d-6、...,此时就需要讨论d的奇偶性。如果d是偶数,那么d可以减到0,即fast最终会追上slow,但是如果d是奇数,那么d不是2的倍数,它会错过slow并新的距离为C-1(假设C是环的节点数),进入新一轮的追击过程,直到他们两的距离是2的倍数,此时这一轮就可以追上了。

永远追不上的条件:同时存在C是偶数且距离d(或N)为奇数,那么就会永远追不上。 

那是否真的会有这种情况呢?我们需要寻找C和N之间的关系:

证明:

假设slow进环时,fast和slow的距离是N,带环部分的节点数为C,链表不带环部分的节点数为L,slow进环时fast已经在环中转了x圈,则有:

slow走的距离是:L

fast走的距离是:L + xC + (C - N)

由于fast走的距离是slow的三倍,则有:3L = L + xC + C - N

化简得到:2L = (x + 1)C - N

显然C为偶数且N为奇数不能同时成立,也就是说,fast最终总是会追击上slow。

 ​​

 题目二:环形链表 II

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

题目描述:

题目分析:

 思路1:快慢指针法。用题目一中的方法找到fast追击上slow的节点,记为meet,再将head记为cur,让meet和cur同时走,它们会再第一个相交节点相遇,即入环的第一个节点。

那为什么会在第一个相交节点相遇呢?

解:

假设fast追上slow时的节点,即meet节点,逆时针距离入环的第一个节点的距离为N,不带环部分节点数为L,带环部分节点数为C,则有:

slow走的距离是:L + N(fast一次走2步,在一圈内一定能追上)

fast走的距离是:L + xC + N

又因为fast走的距离是slow的两倍,则有:2(L + N) = L + xC + N

化简得到:L = xC- N

显然随着x的变化,指针fast在环内距离入环的第一个节点的距离f(x)是一个周期函数,周期为T = 1,那么L(x)也是关于x的周期函数,周期T = 1。

所以:L = C - N(就比如sinπ、sin3π和sin5π都是相等的)

由此得到不带环部分的节点数等于meet距离入环的第一个节点的节点数相等,所以它们以相同速度移动,一定会再第一个相交节点相遇。

代码如下: 

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
typedef struct ListNode ListNode;
struct ListNode* detectCycle(struct ListNode* head) {ListNode* slow = head, * fast = head;//创建快慢指针while (fast && fast->next){slow = slow->next;fast = fast->next->next;if (slow == fast)//fast追上slow{ListNode* meet = slow;ListNode* cur = head;while (meet != cur)//meet和cur相遇,则为第一个相交节点{meet = meet->next;cur = cur->next;}return meet;}}return NULL;//没有相交节点则返回NULL
}

思路2:先用思路1的方法找到meet,然后将meet->next设置为newhead,然后让环断裂,使其转化为相交链表找第一个相交节点(上个篇目解析过这类题)。 

这个思路可能更好想,但是代码却要更加复杂一些。

代码如下: 

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
typedef struct ListNode ListNode;
//相交单链表寻找第一个相交节点
struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB) {ListNode* cur1 = headA, * cur2 = headB;int lenA = 0;int lenB = 0;while (cur1->next)//统计链表A的长度{lenA++;cur1 = cur1->next;}while (cur2->next)//统计链表B的长度{lenB++;cur2 = cur2->next;}if (cur1 != cur2)//判断是否有交点return NULL;//假设法,设置长短链表ListNode* LongList = headA, * ShortList = headB;if (lenA < lenB){LongList = headB;ShortList = headA;}int gap = abs(lenA - lenB);//两链表节点差值while (gap--)//让长的先走差值的步数{LongList = LongList->next;}while (LongList != ShortList)//让两链表一起走,第一个相等的就是交点{LongList = LongList->next;ShortList = ShortList->next;}return LongList;
}
//带环链表寻找第一个相交节点
struct ListNode *detectCycle(struct ListNode *head) {ListNode *slow = head, *fast = head;//创建快慢指针while(fast && fast->next){slow = slow->next;fast = fast->next->next;if(slow == fast){ListNode* meet = slow;ListNode* newhead = meet->next;//新单链表的头meet->next = NULL;//尾部置为NULLListNode* cur = getIntersectionNode(newhead, head);return cur;}}   return NULL;
}

第一个函数我们在上一篇目中有详细解析,这里直接CV就可以了。 虽然能够通过,但是修改了链表,本质上不符合题目要求了,但是也是个值得思考的思路。

 ​​

题目三:随机链表的复制

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

题目描述:

注:深拷贝:拷贝一个值个指向和当前链表一模一样的链表。

题目分析:

 思路:快先将新的节点交错插入到原随机链表中,然后完成设置random后再将新的节点尾插到新链表newhead中。

这道题目创建节点其实不难,难就难在random是随机的,应该如何处理random的指向是这道题目的难点。我们如果错位插入,就可以得到新节点和旧链表之间的关系,那么新的节点的random指针都会指向插入了新节点的链表的random的next指针(空指针除外)。

比如,上面原来的第二个节点的random指向了第一个节点,那么新的第二个节点的random就指向第一个节点的next节点。

代码如下:

 

/*** Definition for a Node.* struct Node {*     int val;*     struct Node *next;*     struct Node *random;* };*/
typedef struct Node Node;
struct Node* copyRandomList(struct Node* head) {Node* cur = head;while (cur)//创建新节点并错位插入旧节点{Node* copy = (Node*)malloc(sizeof(Node));copy->val = cur->val;copy->next = cur->next;cur->next = copy;cur = copy->next;}cur = head;while (cur)//设置random指针的指向{Node* copy = cur->next;if (!cur->random)copy->random = NULL;else{copy->random = cur->random->next;}cur = copy->next;}cur = head;//创建新链表Node* newhead = (Node*)malloc(sizeof(Node));Node* newtail = newhead;while (cur)//将新节点尾插到新链表{Node* copy = cur->next;newtail->next = copy;newtail = newtail->next;cur->next = copy->next;//恢复原链表cur = copy->next;}if (newtail)newtail->next = NULL;return newhead->next;
}

这道题目不论是思路还是代码书写都很有难度,如果你看了我的讲解能够独立地写出上面代码(不一定非要和我一样),那么恭喜你,在当前阶段你的链表已经过关了!

 

SUMUP结尾

数据结构就像数学题,需要刷题才能对它有感觉。之后还会更新数据结构相关的练习题、面试题,希望大家一起学习,共同进步~

如果大家觉得有帮助,麻烦大家点点赞,如果有错误的地方也欢迎大家指出~

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

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

相关文章

《Python编程从入门到实践》day34

# 昨日知识点回顾 json文件提取数据、绘制图表渐变色显示 # 今日知识点学习 第17章 17.1 使用Web API Web API作为网站的一部分&#xff0c;用于与使用具体URL请求特定信息的程序交互&#xff0c;这种请求称为API调用。 17.1.1 Git 和 GitHub Git&#xff1a;分布式版本控制系…

Media Encoder 2024 for Mac媒体编码器安装教程ME2024安装包下载

安装 步骤 1&#xff0c;双击打开下载好的安装包。 2&#xff0c;选择install ame_24...双击打开启动安装程序。 3&#xff0c;点击install。 4&#xff0c;输入电脑密码。 5&#xff0c;软件安装中... 6&#xff0c;安装结束点击好。 7&#xff0c;返回打开的镜像 选择激活补…

零基础,想做一名网络安全工程师,该怎么学习?

​ 相比IT类的其它岗位&#xff0c;网络工程师的学习方向是比较明亮的。想要成为网络工程师&#xff0c;华为认证就是最好的学习方法。而网络工程师的从零开始学习就是从华为认证的初级开始学起&#xff0c;也就是HCIA&#xff0c;也就是从最基本的什么是IP地址、什么是交换机这…

响应式流和reactor框架进阶

响应式流和reactor框架进阶 响应式流创建、转换、处理 本文档主要介绍在响应式编程中如何从流中获取数据并处理。 前提条件 假设您已经能掌握Java基础、Maven使用、Lamda表达式、响应式编程等基础。 如何获取流中数据 &#x1f30f; 说明 1、不要试图从流中获取数据出来&a…

Angular(1):使用Angular CLI创建空项目

要创建一个空的 Angular 项目&#xff0c;可以使用 Angular CLI&#xff08;命令行界面&#xff09;。以下是使用 Angular CLI 创建一个新项目的步骤&#xff1a; 1、安装 Angular CLI&#xff1a; 打开你的命令行界面&#xff08;在 Windows 上是 CMD、PowerShell 或 Git Bas…

使用python绘制一个五颜六色的爱心

使用python绘制一个五颜六色的爱心 介绍效果代码 介绍 使用numpy与matplotlib绘制一个七彩爱心&#xff01; 效果 代码 import numpy as np import matplotlib.pyplot as plt# Heart shape function def heart_shape(t):x 16 * np.sin(t)**3y 13 * np.cos(t) - 5 * np.cos…

微软:最新ChatGPT-4o模型,可在 Azure OpenAI上使用

北京时间5月14日凌晨&#xff0c;OpenAI 一场不到 30 分钟的发布会&#xff0c;正式发布了 GPT-4o&#xff0c;视频语音交互丝滑到吓人&#xff0c;还即将免费可用&#xff01; GPT-4o&#xff0c;其中的「o」代表「omni」&#xff08;即全面、全能的意思&#xff09;&#xff…

AIGC行业:巨头引领的创新浪潮与市场前景

AIGC&#xff08;AI Generated Content&#xff09;技术&#xff0c;作为新兴的技术力量&#xff0c;正逐渐改变内容创作的生态。在这一变革中&#xff0c;国内科技巨头如百度、阿里巴巴、腾讯等的积极参与&#xff0c;不仅为行业带来资本和技术支持&#xff0c;更预示着AIGC技…

react 下拉框内容回显

需要实现效果如下 目前效果如下 思路 : 将下拉框选项的value和label一起存储到state中 , 初始化表单数据时 , 将faqType对应的label查找出来并设置到Form.Item中 , 最后修改useEffect 旧代码 //可以拿到faqType为0 但是却没有回显出下拉框的内容 我需要faqType为0 回显出下拉…

Shell脚本基本命令

文件名后缀.sh 编写shell脚本一定要说明一下在#&#xff01;/bin/bash在进行编写。命令选项空格隔开。Shell脚本是解释的语言&#xff0c;bash 文件名即可打印出编写的脚本。chmod给权限命令。如 chmod 0777 文件名意思是给最高权限。 注意:count赋值不能加空格。取消变量可在变…

如何提升网络性能监控和流量回溯分析的效率?

目录 什么是网络性能监控&#xff1f; 网络性能监控的关键指标 什么是流量回溯分析&#xff1f; 流量回溯分析的应用场景 网络性能监控与流量回溯分析的结合 实例应用&#xff1a;AnaTraf网络流量分析仪 如何选择适合的网络性能监控和流量回溯分析工具&#xff1f; 结论…

MQTT 5.0 报文解析 06:AUTH

欢迎阅读 MQTT 5.0 报文系列 的最后一篇文章。在上一篇中&#xff0c;我们已经介绍了 MQTT 5.0 的 DISCONNECT 报文。现在&#xff0c;我们将介绍 MQTT 中的最后一个控制报文&#xff1a;AUTH。 MQTT 5.0 引入了增强认证特性&#xff0c;它使 MQTT 除了简单密码认证和 Token 认…

Vue3实战笔记(36)—粒子特效完成炫酷的404

文章目录 前言404特效总结 前言 昨天介绍了一个粒子特效小例子&#xff0c;不够直观&#xff0c;下面直接实战在自己的项目中实现一个好玩滴。 404特效 更改之前创建好的404.vue: <template><div class"container"><vue-particles id"tspartic…

阿里云和AWS的CDN产品对比分析

在现代互联网时代,内容分发网络(CDN)已成为确保网站和应用程序高性能和可用性的关键基础设施。作为两家领先的云服务提供商,阿里云和Amazon Web Services(AWS)都提供了成熟的CDN解决方案,帮助企业优化网络传输和提升用户体验。我们九河云一直致力于阿里云和AWS云相关业务&#…

【光伏干货】光伏无人机巡检步骤

随着光伏产业的迅速发展和无人机技术的日益成熟&#xff0c;光伏无人机巡检已成为提高光伏电站运维效率、降低运维成本的重要手段。本文将详细介绍光伏无人机巡检的步骤&#xff0c;帮助读者更好地理解和应用这一技术。 一、前期准备 1、设备检查&#xff1a;对无人机及其相关…

mysql内存和磁盘的关系

mysql内存和磁盘的关系 1.MySQL的内存和磁盘之间的关系是密切的。MySQL的数据存储在磁盘上&#xff0c;但为了高效地执行查询操作&#xff0c;它也会将数据页&#xff08;每个页通常为16KB&#xff09;读入内存。MySQL的缓冲池&#xff08;buffer pool&#xff09;是在内存中的…

谷歌插件编写

目录 manifest.json {"manifest_version": 3,"name": "Floating Ball","version": "1.0","description": "A floating ball on the right side of the webpage.","permissions": ["act…

【算法】位运算算法——两整数之和

题解&#xff1a;两整数之和(位运算算法) 目录 1.题目2.位运算算法3.参考代码4.总结 1.题目 题目链接&#xff1a;LINK 2.位运算算法 这个题目难点就在于不能用、- 那什么能够代替加号呢&#xff1f; 既然数的层面不能用号&#xff0c;那二进制的角度去用号即可。 恰好&a…

MySQL 数据类型和搜索引擎

文章目录 【 1. 数据类型 】1.1 数值类型1.1.1 整型1.1.2 小数1.1.3 数值类型的选择 1.2 日期和时间YEAR 年TIME 时间DATE 日期DATETIME 日期时间TIMESTAMP 时间戳日期和时间的选择 1.3 文本字符串CHAR 固定字符串、VARCHAR 可变字符串TEXT 文本ENUM 枚举SET 集合字符串类型的选…

假如有几十个请求,如何去控制高并发?

公司项目中做图片或文件批量下载&#xff0c;每次下载都是大批量的&#xff0c;那么假如我一次性下载几十个&#xff0c;如何去控制并发请求的&#xff1f; 让我想想&#xff0c;额~&#xff0c; 选中ID&#xff0c;循环请求&#xff1f;&#xff0c;八嘎&#xff01;肯定不是那…