当前位置: 首页 > news >正文

【链表OJ】常见面试题 3

文章目录

  • 1.[环形链表II](https://leetcode.cn/problems/linked-list-cycle-ii/description/)
  • 1.1 题目要求
    • 1.2 快慢指针
    • 1.3 哈希法
  • 2.[随机链表的复制](https://leetcode.cn/problems/copy-list-with-random-pointer/description/)
    • 2.1 题目要求
    • 2.2 迭代法

1.环形链表II

环形链表II

1.1 题目要求

找到环形链表的入口并返回该节点,如果找不到就返回NULL。

1.2 快慢指针

在话 环形链表I中我们就用到了,快慢指针来判断一个链表中是否存在环。在环形链表I中已经解释了为什么会相遇。可是现在的问题是找到环的入口,我们的快慢指针好像做不到吧。
别急嘛,下面我将用数学的方式来证明可以做到!
数学证明
初始时,快慢指针都在链表的起始位置,在指针开始运动前我们要了解,快指针的速度的慢指针的两倍,也就说明了快指针的运动的路程是慢指针的两倍
定义快指针为红色箭头,慢指针为蓝色箭头。
起始

运动开始,当运动到慢指针刚好进入到环中时,快指针已经在环中运动了k圈了(k>=0
慢指针开始入环

此时的慢指针在A点,快指针在B点。AB距离为x,BA距离为y慢指针运动路程为z,快指针运动距离为k*(x+y)+x
根据快指针的运动路程是慢指针的两倍可得

2*z = k*(x+y)+x;
化简为
z = k*(x+y)+x

将图中的z替换得:
过渡

下面就是快慢指针相遇时刻,根据图中得距离BA为y,因为快指针的速度是慢指针的两倍,那么就说明了它们的相遇时刻是慢指针再运动y距离的时刻,此时的快指针运动了2y
快指针与慢指针相遇

现在它们相遇了,从图中观察,AC的距离为x。然后环的大小为x+y,以及从head到A的距离为x+k(x+y),这不就说明了,我们只要派出一个慢指针从head运动到A不就可以了吗,让环慢指针在环中转k圈,环外的慢指针也运动了k(x+y)的距离,此时它们离A都只差x,同时速度又是一样,由此两个慢指针是会在A点相遇的。

证明过程中的图片来源:Shawxing精讲算法

struct ListNode *detectCycle(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){struct ListNode* cur = head;while(cur!=slow){cur = cur->next;slow = slow->next;}if(cur==slow)return cur;}}return NULL;
}

1.3 哈希法

利用哈希表unordered_map来存储链表的每个节点,链表存在环时,一定会有重复的节点进入哈希表,我们只要关注第一个重复加入哈希表的节点即可。

用c写很麻烦,代码我用c++写的。

class Solution {
public:ListNode *detectCycle(ListNode *head) {unordered_map<ListNode*,bool> cnt;ListNode* cur = head;while(cur){if(cnt.find(cur)!=cnt.end()){return cur;}cnt[cur] = true;cur = cur->next;}return nullptr;}
};

2.随机链表的复制

随机链表的复制

2.1 题目要求

创建一个新链表,这个新链表所有的节点、next链接和random链接都要与原链表完全相同,返回新链表的头。

2.2 迭代法

先创建和原链表值相同的节点,让原链表中的节点指向新创建的节点前,用新创建的节点指向原节点的下一个节点。
copy节点的创建

处理random
在把cur指向head,重新遍历链表,因为原本的链表因为新节点的加入有所改变,当时我们还是要让cur每次都指向原链表的节点,再创建一个copy指向新加入的链表。
因为一一配对的原因,我们只需要让copy节点指向原先节点指向的random的下一个节点就可以了就可以,不过有个例外就指向NULL的节点,特别判断一下就可以了
copy的random的指向

链接copy节点
把copy指向原链表节点的指针统统指向copy节点就可以了
copy节点最后的链接

struct 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;copy->random = NULL;cur = copy->next;}cur = head;while(cur){struct Node* copy = cur->next;struct Node* next = copy->next;if(cur->random == NULL)copy->random = NULL;elsecopy->random = cur->random->next;cur = next;}//链接copy节点struct Node* phead = NULL;struct Node* tail = NULL;cur = head;while(cur){struct Node* copy = cur->next;struct Node* next = copy->next;if(phead == NULL){phead = copy;tail = phead;}else{tail->next = copy;tail = copy;}cur = next;}return phead;
}

那么关于链表题目的讲解就先到此为止了,如果大家对链表的题目还是很感兴趣下去以后可以刷这里的题:力扣链表和牛客链表的题目

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Linux kill命令给进程发信号
  • 寻找二叉树中两个节点的最低公共祖先
  • 2024小学生古诗文大会暑期备考:吃透历年真题和知识点(持续)
  • 简单的docker学习 第1章 docker 概述
  • springcloud loadbalancer nacos无损发布
  • 【数据结构】线段树
  • 临床数据科学中如何用R来进行缺失值的处理(上)
  • 24/8/6算法笔记 不同核函数
  • 读友好的缓存淘汰算法
  • Go语言依赖管理:如何配置和恢复Go模块镜像
  • 【python】Linux升级版本
  • python 装饰器记录函数用时
  • stm32应用、项目
  • RNN循环网络层
  • PostgreSQL(二十五)PG_FDW的使用
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • 【css3】浏览器内核及其兼容性
  • 【译】理解JavaScript:new 关键字
  • Android Volley源码解析
  • Cookie 在前端中的实践
  • crontab执行失败的多种原因
  • E-HPC支持多队列管理和自动伸缩
  • Java知识点总结(JavaIO-打印流)
  • Spring-boot 启动时碰到的错误
  • Spring核心 Bean的高级装配
  • Spring技术内幕笔记(2):Spring MVC 与 Web
  • Theano - 导数
  • vue从入门到进阶:计算属性computed与侦听器watch(三)
  • 从输入URL到页面加载发生了什么
  • 分享几个不错的工具
  • 工作手记之html2canvas使用概述
  • 区块链共识机制优缺点对比都是什么
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 实战|智能家居行业移动应用性能分析
  • 使用Tinker来调试Laravel应用程序的数据以及使用Tinker一些总结
  • 400多位云计算专家和开发者,加入了同一个组织 ...
  • 进程与线程(三)——进程/线程间通信
  • 如何在招聘中考核.NET架构师
  • 智能情侣枕Pillow Talk,倾听彼此的心跳
  • ​插件化DPI在商用WIFI中的价值
  • #图像处理
  • (C语言)球球大作战
  • (PySpark)RDD实验实战——取最大数出现的次数
  • (阿里云在线播放)基于SpringBoot+Vue前后端分离的在线教育平台项目
  • (求助)用傲游上csdn博客时标签栏和网址栏一直显示袁萌 的头像
  • (四)库存超卖案例实战——优化redis分布式锁
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • (转)IOS中获取各种文件的目录路径的方法
  • (转载)CentOS查看系统信息|CentOS查看命令
  • .dwp和.webpart的区别
  • .net 8 发布了,试下微软最近强推的MAUI
  • .NET Core 2.1路线图
  • .NET Core SkiaSharp 替代 System.Drawing.Common 的一些用法
  • .Net 高效开发之不可错过的实用工具
  • .NET 给NuGet包添加Readme