三个有意思的链表面试题的完成

上一篇博客我们已经完成了链表的所有内容,那么这一篇博客我们来看一下三个特别有意思的链表题目。

**第一个题目如下:**

在这里插入图片描述
在这里插入图片描述
相信不少朋友看到这题目就已经晕了,那就简单说明下这个题目,题目就是创建一个链表,其中每个节点有两部分–指针域与数值域,指针域里也有两个指针next(指向下一个节点),random(随机指向),要求我们拷贝一份这个链表,使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。
在这里插入图片描述

也就是上图的形式,这个题目如果单纯的只拷贝一份链表和每个节点的val,相信大家可以很快的做出,也就是遍历一下原链表,遍历一个节点创建一个新的节点并拷贝值,最后将节点连接形成链表即可。但现在增加了一个random指针,我们该如何解决这个问题呢?

受限于当前的知识,我们可用的方法很少,下面是一个很巧妙的思路:
1、创建新的节点,构造新链表
在这里插入图片描述
我们可以遍历一个节点拷贝一个节点,并且将这个新的节点插入至原节点的后面。

2、完成random的指向
在这里插入图片描述
当我们把这一步以图像的形式展现,我们就可以发现新链表当前节点的random指针是不是指向原链表原节点的random->next指向的节点

3、取下拷贝的节点,形成题目要求的链表
在这里插入图片描述
把这个节点连接形成新的链表,我们可以使用之前学过的尾插,头插都是可以的。

最后还有一个小细节,就是如果我们只取下节点,那原链表是不是被我们断开了,我们可以恢复原链表的结构也可以不恢复,题目里没有说明就不用管。

代码如下:

/*** Definition for a Node.* struct Node {*     int val;*     struct Node *next;*     struct Node *random;* };*/
struct Node* copyRandomList(struct Node* head) {struct Node*pcur=head;//创建遍历原链表的指针pcurwhile(pcur){struct Node*newnode=(struct Node*)malloc(sizeof(struct Node));newnode->val=pcur->val;newnode->next=pcur->next;pcur->next=newnode;pcur=newnode->next;}//这一部分就是拷贝节点,并插入原节点后面struct Node*cur=head;//同样为遍历链表的节点while(cur){struct Node*newnode=cur->next;if(cur->random==NULL){newnode->random=NULL;}else{newnode->random=cur->random->next;}cur=newnode->next;}//这一部分完成的是新节点的random的指向struct Node*phead=NULL;//创建一个新的链表phead为头指针,ptail为尾指针struct Node*ptail=NULL;struct Node*Cur=head;while(Cur){struct Node*node=Cur->next;//node指向的是原链表的新节点struct Node*next=node->next;//next指向的是原链表的原节点if(ptail==NULL)//如果新链表为空{phead=ptail=node;}else//链表不为空{ptail->next=node;ptail=ptail->next;}Cur=next;}return phead;//返回新链表的头}
**第二个题目如下:**

在这里插入图片描述
在这里插入图片描述
这道题目代码比较简单,想要理解透彻还是有一定难度的。

思路如下:
在这里插入图片描述
就是使用快慢指针,快指针一步走两个节点,慢指针一步走一个节点,让慢指针去追这个快指针,当追上的时候也就是fast==slow,那就证明带环,如果一直追不上那就不带环。

那一定追的上吗?有没有可能出现错过的情况?快指针可以一步走三个节点吗?走三个节点会不会错过呢?这几个问题就是我们现在需要解决的。

第一个问题:那一定追的上吗?有没有可能出现错过的情况?

在这里插入图片描述
从现在开始,fast走两步,slow走一步,那么两指针每走一步,它们之间的距离减小1,所以N取任何值slow与fast指针都会相遇,故不存在错过的情况。

第二个问题:快指针可以一步走三个节点吗?走三个节点会不会错过呢?

由上面的图我们可以推出:
在这里插入图片描述
那么我们可以总结一下:
当N为偶数时,无论R为奇数偶数,都能够追上,也就是不会错过。
当N为奇数,R为奇数时,能够追上;
当N为奇数,R为偶数时,永远追不上。

但是存不存在N为奇数,R为偶数这种情况?
在这里插入图片描述
由上面得出的结论就是fast一步走三个节点,一定能追上。

根据上面的推导过程,fast一步走4个节点、5个节点都是可以推出来的。

代码实现很简单:

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
bool hasCycle(struct ListNode *head) {struct ListNode*fast=head;struct ListNode*slow=head;while(fast&&fast->next){fast=fast->next->next;slow=slow->next;if(fast==slow){return true;}}return false;
}
**第三个题目:**

在这里插入图片描述
这个题目就是在上一个题目的基础上更加深入一点,需要我们返回这个循环的初始节点;

第一步:判断环的有无
因为这一步与上一个题目基本一样,所以我这里就不再重复了;

第二步:让slow走到fast的位置,也就是让两个指针相遇定义为meet,返回当前节点,这一步也可以通过前一个题目实现;

第三步:让pcur从链表的头开始走,同时meet也开始在环内走,当两者相等时,两指针指向的节点就是开始循环的节点。

下面我们就来讨论为什么:
在这里插入图片描述
代码实现:

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/struct ListNode*fastnode(struct ListNode*head)
{struct ListNode*fast=head;struct ListNode*slow=head;while(fast&&fast->next){fast=fast->next->next;slow=slow->next;if(slow==fast){return fast;//这里我没有创建新的meet指针,当两者相等时,返回其中一个效果相同}}return NULL;//判断是否有环
}struct ListNode *detectCycle(struct ListNode *head) {struct ListNode*fast=fastnode(head);if(fast==NULL)//如果链表没有环就直接返回NULL{return NULL;}struct ListNode*slow=head;while(slow!=fast)//这一步就是让两指针相遇,返回相遇时的节点,也就是环开始的节点{slow=slow->next;fast=fast->next;}return fast;
}

最后一个题还有一种做法,那就是将meet指向的节点断开,那现在整个题目就变为了相交链表求相交节点的问题了,这里只简单的说明一下思路,有兴趣的可以下来实现一下;
在这里插入图片描述

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

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

相关文章

Android14 - 绘制系统 - 概览

从Android 12开始,Android的绘制系统有结构性变化, 在绘制的生产消费者模式中,新增BLASTBufferQueue,客户端进程自行进行queue的生产和消费,随后通过Transation提交到SurfaceFlinger,如此可以使得各进程将缓…

【vue3+elementuiplus】el-select下拉框会自动触发校验规则

场景:编辑弹框省份字段下拉框必填,触发方式change,有值第一次打开不会触发校验提示,关闭弹框再次打开触发必填校验提示,但是该字段有值 问题的原因是:在关闭弹层事件中,我做了resetfileds&…

SpringBoot + MybatisPlus

SpringBoot MybatisPlus 整合记录 1. 硬件软件基本信息2. 相关链接3. 通过idea快速生成一个Springboot项目4. 启动报错问题解决问题一:Springboot启动的时候报错提示 “没有符合条件的Bean关于Mapper类型”问题二:启动的时候提示需要一个Bean&#xff0…

电磁仿真--CST网格介绍

1. 简介 网格会影响仿真的准确性和速度,花时间理解网格化过程是很重要的。 CST 中可用的数值方法包括FIT、TLM、FEM、MoM,使用不同类型的网格: FIT和TLM:六面体 FEM:四面体、平面 MoM:表面 CFD&#…

深入理解与防御跨站脚本攻击(XSS):从搭建实验环境到实战演练的全面教程

跨站脚本攻击(XSS)是一种常见的网络攻击手段,它允许攻击者在受害者的浏览器中执行恶意脚本。以下是一个XSS攻击的实操教程,包括搭建实验环境、编写测试程序代码、挖掘和攻击XSS漏洞的步骤。 搭建实验环境 1. 安装DVWA&#xff…

【408真题】2009-16

“接”是针对题目进行必要的分析,比较简略; “化”是对题目中所涉及到的知识点进行详细解释; “发”是对此题型的解题套路总结,并结合历年真题或者典型例题进行运用。 涉及到的知识全部来源于王道各科教材(2025版&…

推荐一个快速开发接私活神器

文章目录 前言一、项目介绍二、项目地址三、功能介绍四、页面显示登录页面菜单管理图表展示定时任务管理用户管理代码生成 五、视频讲解总结 前言 大家好!我是智航云科技,今天为大家分享一个快速开发接私活神器。 一、项目介绍 人人开源是一个提供多种…

Golang | Leetcode Golang题解之第112题路径总和

题目: 题解: func hasPathSum(root *TreeNode, sum int) bool {if root nil {return false}if root.Left nil && root.Right nil {return sum root.Val}return hasPathSum(root.Left, sum - root.Val) || hasPathSum(root.Right, sum - roo…

C++常见知识点总结

常见字符 * 注释:/* 这是一个注释*/乘法:a * b取值运算符:*指针变量,int a 4,*a ????指针变量:数据类型 *变量名, int *no &bh&#xff0…

SAP揭秘者-怎么执行生产订单ATP检查及其注意点

文章摘要: 上篇文章给大家介绍生产订单ATP检查的相关后台配置,大家可以按照配置步骤去进行配置,配置完之后,我们接下来就是要执行ATP检查。本篇文章具体给大家介绍怎么来执行生产 订单ATP检查及其注意点。 执行生产订单ATP检查的…

Qt for android 获取USB设备列表(二)JNI方式 获取

简介 基于上篇 [Qt for android 获取USB设备列表(一)Java方式 获取], 这篇就纯粹多了, 直接将上篇代码转换成JNI方式即可。即所有的设备连接与上篇一致。 (https://listentome.blog.csdn.net/article/details/139205850) 关键代码…

Android卡顿丢帧低内存与adb shell内存状态

Android卡顿丢帧低内存与adb shell内存状态 卡顿丢帧除了CPU/GPU层面,另外,也需要特别注意整机低内存情况。kswapd0 是一个内核工作线程,内存不足时会被唤醒,做内存回收工作。 当内存频繁在低水位的时候,kswapd0 会被频…

Linux基础(六):Linux 系统上 C 程序的编译与调试

本篇博客详细分析,Linux平台上C程序的编译过程与调试方法,这也是我们后续程序开发的基础。 目录 一、第一个hello world程序 1.1 创建.c文件 1.2 编译链接 运行可执行程序 二、编译链接过程 2.1 预编译阶段 2.2 编译阶段 2.3 汇编阶段 2.4 链…

qemu+gdb调试linux内核

打开CONFIG_DEBUG_INFO,编译内核 通过图形菜单配置该宏,执行make menuconfig。 kernel hacking —> compile-time checks and compiler options —> compile the kernel with debug info 验证是否打开成功,grep -nr “CONFIG_DEBUG_INFO” .config。 打开成功,然后…

plsql 学习

过程化编程语言 赋值:: ||:连接符号 dbms_output.put_line() :输出的语句 var_name ACCOUNTLIBRARY.USERNAME%type; 变量名;某个表的数据类型;赋值给变量名 用下面的方法更好用 异常exception 循…

力扣HOT100 - 75. 颜色分类

解题思路&#xff1a; 单指针&#xff0c;对数组进行两次遍历。 class Solution {public void sortColors(int[] nums) {int p 0;int n nums.length;for (int i 0; i < n; i) {if (nums[i] 0) {int tmp nums[i];nums[i] nums[p];nums[p] tmp;p;}}for (int i p; i …

存储+调优:存储-IP-SAN-EXTENSION

存储调优&#xff1a;存储-IP-SAN-EXTENSION 文件系统的锁标记 GFS&#xff08;锁表空间&#xff09; ----------- ------------ ------------- 节点 | ndoe1 | | node2 | | node3 | ---------- ------…

GNSS中的多路径效应原理及计算方法

1 多路径效应原理 图1 多路径效应原理图 2 计算方法 如需原文&#xff0c;可加多源融合定位与智能控制讨论群获取,QQ群号&#xff1a;51885949

【OceanBase诊断调优】—— 直连普通租户时遇到报错:Tenant not in this server

本文介绍了直连 OceanBase 数据库中的普通租户时&#xff0c;出现报错&#xff1a;ERROR 5150 (HY000) : Tenant not in this server 的处理方法。 问题描述 在 n-n 或者 n-n-n (n>1) 的部署架构中&#xff0c;使用 2881 端口 直连 OceanBase 集群的普通租户&#xff0c;可…

SpringBoot运维篇(打包,多环境,日志)

文章目录 一、SpringBoot程序的打包与运行二、配置高级三、多环境开发四、日志 一、SpringBoot程序的打包与运行 刚开始做开发学习的小伙伴可能在有一个知识上面有错误的认知&#xff0c;我们天天写程序是在Idea下写的&#xff0c;运行也是在Idea下运行的。 ​但是实际开发完成…