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

链表学习之找到两个链表相交的第一个节点

链表解题技巧

  • 额外的数据结构(哈希表);
  • 快慢指针;
  • 虚拟头节点;

找到两个链表相交的第一个节点

给定两个链表,这两个链表可能有环,可能无环。判断这两个链表是否相交,相交则返回第一个相交的节点,不相交则返回nullptr。

首先,需要判断两个链表是否有环,有环的话入环节点的位置在哪?

然后,分情况判断两个链表是否相交:

  • 两个无环链表:对于两个无环链表;
  • 一个有环一个无环:不可能相交
  • 两个有环链表:入环点相同(一定相交)、入环点不相同;
ListNode* LinkedList::findFirstIntersection(ListNode *head1, ListNode *head2) {if (head1 == nullptr || head2 == nullptr) {return nullptr;}// has cycleListNode *loop1 = hasCycle(head1);ListNode *loop2 = hasCycle(head2);// if (loop1 == nullptr && loop2 == nullptr) return findFirstIntersectionWithNoLoop(head1, head2);if (loop1 != nullptr && loop2 != nullptr) return findFirstIntersectionWithLoops(head1, loop1, head2, loop2);return nullptr;
}

链表是否有环

方法1:哈希表(时:O(N),空:O(N))

使用哈希表,在链表遍历过程中,判断该节点是否在哈希表中:

  • 该节点在表中,则说明有环,此时为入环第一个节点,返回该节点并退出;
  • 该节点不在表中,说明无环,将节点指针加入表中,继续遍历;
  • 遍历到空,则说明无环。
ListNode* LinkedList::hasCycleBySet(ListNode *head) {if (head == nullptr || head->next == nullptr) return nullptr;std::unordered_set<ListNode*> set;ListNode *cur = head;while (cur) {if (set.find(cur) != set.end()) {return cur;}set.insert(cur);cur = cur->next;}return nullptr;
}

方法2:快慢指针(时:O(N), 空:O(1))

在快慢指针遍历链表的过程中,如果快指针遍历到nullptr,则说明无环。

如果有环,快慢指针一定会在环内相遇,当相遇发生之后,快指针回到头节点,慢指针不动,快慢指针同时一次一步的移动,直至相遇,相遇的位置即为入环的第一个节点。

ListNode* LinkedList::hasCycle(ListNode *head) {if (head == nullptr || head->next == nullptr) return nullptr;ListNode *slow = head;ListNode *fast = head;while (fast != nullptr && fast->next != nullptr) {slow = slow->next;fast = fast->next->next;if (slow == fast) {fast = head;while (fast != slow) {slow = slow->next;fast = fast->next;}return slow;}}return nullptr;
}
Notes

fast和slow必须同时从head出发!(fast=head->next,slow=head这样的出发就会差一个节点,永远无法结束)

链表相交

无环链表相交

最好理解和想到的方法就是,遍历两个链表,计算出两个链表的长度差值,让长链表先移动差值步,接着继续同时遍历,直到相遇或都为nullptr。

ListNode* LinkedList::findFirstIntersectionWithNoLoop(ListNode *head1, ListNode *head2) {ListNode *cur1 = head1;ListNode *cur2 = head2;int diff = 0;while (cur1) {cur1 = cur1->next;diff++;}while (cur2) {cur2 = cur2->next;diff--;}cur1 = diff > 0 ? head1 : head2; // cur1 -> the longer listcur2 = cur1 == head2 ? head1 : head2;diff = diff < 0 ? -diff : diff; // abs// cur1 move diff steps firstwhile (diff--) cur1 = cur1->next;while (cur1 != cur2) {cur1 = cur1->next;cur2 = cur2->next;}return cur1;
}

或者使用交换遍历的方式,因为无论如何两个链表都遍历的话,最后要不就相交,要不就都为nullptr。

注意,两个节点和一个节点相交时的循环判断。

ListNode* LinkedList::findFirstIntersectionWithNoLoopEx(ListNode *head1, ListNode *head2) {ListNode *cur1 = head1;ListNode *cur2 = head2;while ( cur1 != cur2 ) {cur1 = cur1 ? cur1->next : head2;cur2 = cur2 ? cur2->next : head1;}return cur1;
}

有环链表相交

有环链表有入环节点相同和入环节点不同两种情况:

  • 入环节点相同的话肯定相交,交点也一定在头节点到入环节点之间,等价于无环链表相交;
  • 入环节点不同的情况下:如果相交则,这两个节点一定都在一个环上,从其中一个节点开始遍历,到回到这个节点的过程中,如果没有遇到另外一个节点,则说明不相交,反之相交,随意返回其中一个节点即可。
ListNode* LinkedList::findFirstIntersectionWithLoops(ListNode *head1, ListNode *loop1, ListNode *head2, ListNode *loop2) {if (loop1 == loop2) {ListNode *cur1 = head1;ListNode *cur2 = head2;while (cur1 != cur2) {cur1 = cur1->next == loop1->next ? head2 : cur1->next;cur2 = cur2->next == loop1->next ? head1 : cur2->next;}return cur1;} else {ListNode *cur = loop1->next;while (cur != loop1) {cur = cur->next;if (cur == loop2) return cur;}return nullptr;}
}

相关文章:

链表学习之找到两个链表相交的第一个节点

链表解题技巧 额外的数据结构&#xff08;哈希表&#xff09;&#xff1b;快慢指针&#xff1b;虚拟头节点&#xff1b; 找到两个链表相交的第一个节点 给定两个链表&#xff0c;这两个链表可能有环&#xff0c;可能无环。判断这两个链表是否相交&#xff0c;相交则返回第一…...

【Kubernetes】【十一】Pod详解 Pod的生命周期

Pod生命周期 我们一般将pod对象从创建至终的这段时间范围称为pod的生命周期&#xff0c;它主要包含下面的过程&#xff1a; pod创建过程 运行初始化容器&#xff08;init container&#xff09;过程 运行主容器&#xff08;main container&#xff09; 容器启动后钩子&#…...

Connext DDS录制服务 Recording Service(1)

1 序言 1.1 简介 RTI记录服务包括以下工具: •记录服务,一种RTI Connext DDS应用程序,用于记录主题和发现数据。记录服务记录数据更新以及时间戳,因此您可以查看或回放系统中随时间发生的数据更新。默认情况下,记录的数据存储在SQLite文件中。录制服务还具有一个API,用于…...

vTESTstudio - VT System CAPL Functions - VT2004(续2)

不要沮丧&#xff0c;不必惊慌&#xff0c;做努力爬的蜗牛或坚持飞的笨鸟&#xff0c;我们试着长大&#xff0c;一路跌跌撞撞&#xff0c;哪怕遍体鳞伤。vtsSetPWMVoltageLow - 设置PWM输出上的低电压功能&#xff1a;指定数字输出信号&#xff08;尤其是PWM信号&#xff09;输…...

每天一个linux命令---awk

awk命令 1. 简介 awk是一种处理文本文件的语言&#xff0c;是一个强大的文本分析工具&#xff0c;grep、sed、awk并称为shell中文本处理的三剑客。 AWK 是一种处理文本文件的语言&#xff0c;是一个强大的文本分析工具。 之所以叫 AWK 是因为其取了三位创始人 Alfred Aho&am…...

Open3D 点云旋转之轴角式(Python版本)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 三维空间中表示旋转的方法有很多种,轴角式是其中非常经典的一种表示方式。虽然欧拉角表示旋转的方法很是常用,但欧拉角存在着万向锁这个问题,因此轴角式旋转在旋转使用中更为合适。其原理也很是明了,如下所述:…...

Error: Timeout trying to fetch resolutions from npm

文章目录问题描述【最终解决】我搜索到的解决方案npmjs 该依赖各版本列表及对应的被下载次数github issue 说降级到0.0.3就可以正常运行了SOF 也说降级别到0.0.3问题描述 在项目里用到了 "preinstall": "npx npm-force-resolutions"配置&#xff0c;在一台…...

Python基础3

目录 1. 函数多返回值 2. 函数多种传参方式 3. 匿名函数 3.1 函数作为参数传递 3.2 lambda匿名函数 4. 文件的读取操作 4.1 open&#xff08;&#xff09;打开函数 4.2 读操作方法 4.3 文件的写入 4.4 文件的追加 5. 异常的捕获方法 5.1 捕获常规异常 5.2 捕获指定…...

高可用集群(HAC)

1、高可用集群keepalive说明 高可用定义&#xff1a; 目的&#xff1a;尽可能的提高服务的可用性 99%、99.9%、99.99%、99.999% 实现原理&#xff1a;心跳检测服务&#xff1a; 有状态&#xff1a; MySQL 无状态&#xff1a; apacheLVS Keepalive原理 案例环境专为 LVS和…...

python基于django微信小程序的适老化老人健康预警小程序

随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生,各行各业相继进入信息管理时代, 适老化老人健康预警微信小程序就是信息时代变革中的产物之一。 任何系统都要遵…...

基于微信小程序图书馆管理系统

开发工具&#xff1a;IDEA、微信小程序服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8项目构建&#xff1a;maven数据库&#xff1a;mysql5.7前端技术&#xff1a;vue、uniapp服务端技术&#xff1a;springbootmybatis-plus本系统分微信小程序和管理后台两部分&#xff0c;项…...

将镭神C32激光雷达的PointXYZ数据转化为PointXYZIR格式 - 附代码

之前遇到过“镭神32线激光雷达ROS下运行fromRosMsg()报错 Failed to find match for field “intensity“ 问题”&#xff0c; 当时确定了是镭神C32雷达缺少相应字段&#xff0c;并记录博客【学习记录】镭神32线激光雷达ROS下运行fromRosMsg()报错 Failed to find match for fi…...

高级前端一面面试题集锦

详细说明 Event loop 众所周知 JS 是门非阻塞单线程语言&#xff0c;因为在最初 JS 就是为了和浏览器交互而诞生的。如果 JS 是门多线程的语言话&#xff0c;我们在多个线程中处理 DOM 就可能会发生问题&#xff08;一个线程中新加节点&#xff0c;另一个线程中删除节点&#…...

Java基础 -- List集合

Java基础 -- List集合1. Introduction1.1 好处1.2 常用泛型2. 交集&#xff0c;差集等2.1 自身的方法2.2 1.8jdk stream 新特性2.3 Apache的CollectionUtils工具类&#xff08;推荐&#xff09;3. 限定泛型范围4. Awakening1. Introduction 1.1 好处 代码复用&#xff0c;多种…...

【Linux】网络编程 - Socket套接字/基于UDP的网络通信

目录 一.套接字 1.什么是套接字/Socket套接字 2.套接字的分类 3.Socket套接字的常见API 二.网络字节序 1.什么是网络字节序 2.网络字节序和主机字节序的转换接口 三.IP地址形式上的转换 四.客户端的套接字不由程序员bind 1.为什么客户端套接字不能由程序员bind 2.OS…...

流程引擎之Camunda简介

背景Camunda 是支持 BPMN&#xff08;工作流和流程自动化&#xff09;、CMMN&#xff08;案例管理&#xff09; 和 DMN&#xff08;业务决策管理&#xff09; java 框架。Camunda 基于Activiti5 保留了 PVM&#xff0c;其开发团队也是从 activiti 中分裂出来的。Camunda 来自拉…...

Mybatis笔记整理

1. 相关文档地址 中文文档 https://mybatis.org/mybatis-3/zh/index.htmlMybatis可以配置成适应多种环境&#xff0c;不过每个SqlSessionFactory实例只能选择一种环境。Mybatis默认事务管理器是JDBC&#xff0c;连接池&#xff1a;POOLEDMaven仓库:下载地址<dependency>…...

【react全家桶】面向组件编程

文章目录02 【面向组件编程】1.组件的使用1.1 函数式组件1.2 类式组件1.3 组合组件1.4 提取组件组件实例的三大属性 state props refs2.state2.1 基本使用2.2 setState()2.3 简化版本2.4 State 的更新可能是异步的2.5 异步更新解决方案2.6 数据是向下流动的3.props3.1 基本使用…...

Django框架之模型视图-使用 PostMan 对请求进行测试

使用 PostMan 对请求进行测试 PostMan 是一款功能强大的网页调试与发送网页 HTTP 请求的 Chrome 插件&#xff0c;可以直接去对我们写出来的路由和视图函数进行调试&#xff0c;作为后端程序员是必须要知道的一个工具。 安装方式1&#xff1a;去 Chrome 商店直接搜索 PostMan…...

(考研湖科大教书匠计算机网络)第五章传输层-第四节:TCP流量控制

获取pdf&#xff1a;密码7281专栏目录首页&#xff1a;【专栏必读】考研湖科大教书匠计算机网络笔记导航 文章目录一&#xff1a;流量控制概述二&#xff1a;流量控制举例三&#xff1a;拓展阅读&#xff08;可不看&#xff09;&#xff08;1&#xff09;TCP流量控制完整例子&a…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...