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

算法 | 单链表相交

题目:两个单链表头结点为 headA 和 headB,判断两个单链表是否相交?相交的第一个节点是?不相交,则返回null


🧩 省流总结表(性能优化对比)

方法思路时间复杂度空间复杂度是否能找到相交节点性能思路
暴力法双重循环O(mn)O(1)❌ 差双重循环遍历所有节点,比较 pA === pB 是否为同一节点引用。
栈法尾部比较O(m+n)O(m+n)✅(最快)⚙️ 一般将两个链表节点分别入栈。若栈顶不同,则不相交;若相同则出栈比较,直到遇到不同节点,前一个相同节点即为第一个相交点。
哈希法哈希存储O(m+n)O(m)⚙️ 较好遍历链表A,用 Set 存储节点引用;再遍历链表B,若某节点已存在于 Set 中,即为第一个相交节点。
双指针法指针切换O(m+n)O(1)🚀 最优指针A/B分别遍历两个链表,走完自己后切换到对方链表头;最终两指针相遇的节点(或null)即为相交点。
长度差法先走长度差O(m+n)O(1)🚀 最优先求两个链表长度差d,长链表先走d步;然后同时遍历,首次 pA===pB 即为相交节点。

245方法的图解:


分析:若两个单链表相交,则他们从相交的节点开始 会指向同一个内存地址,之后的节点都相同,形成 "Y" 字的形状。


1. 暴力求解

双重 for 循环遍历两个单链表,依次判断两个单链表的节点是否相等,时间复杂度O(m * n),空间复杂度O(1)

function isIntersect(headA, headB) {let pA = headA;while (pA) {let pB = headB;while (pB) {if (pA === pB) return true;  // 地址相同pB = pB.next;}pA = pA.next;}return false;
}

2. 栈方法(判断相交 最快)

将两个单链表存到两个栈中,判断栈顶是否相等,若栈顶相等 则表示两单链表相交。依次分别出栈,判断两个节点是否相等,直到不相等的节点,它的前一个相等节点 是第一个相交的节点。时间复杂度O(m + n),空间复杂度O(m + n)

function getIntersectionNodeByStack(headA, headB){const stackA = [], stackB = [];let pA = headA, pB = headB;while(pA){ stackA.push(pA); pA = pA.next; }while(pB){ stackB.push(pB); pB = pB.next; }let lastCommon = null;while(stackA.length && stackB.length){const a = stackA.pop();const b = stackB.pop();if(a === b){lastCommon = a;} else {break;}}return lastCommon;
}

3. 哈希表

使用 Set 哈希表,将一个单链表使用 ES6的 Set 哈希表存储(const set = new set(),set.add(pA) ),循环遍历检查另一个单链表的节点 是否在 set 中(set.has(pB)),若存在 set 中,则 pB 为第一个相交节点。时间复杂度:O(m+n),空间复杂度O(m)

function getIntersectionNodeByHash(headA, headB){const set = new Set();let pA = headA;while(pA){set.add(pA);pA = pA.next;}let pB = headB;while(pB){if(set.has(pB)) return pB; pB = pB.next;}return null;
}

4. 双指针法(推荐最优)

两个指针分别遍历两个单链表,遍历完(到达链表的尾部)后 再遍历另一个单链表的表头。在第二轮遍历中,判断节点是否相等;若相等,则为他们的第一个相交节点(可以是null,表示不相交)。时间复杂度:O(m+n),空间复杂度O(1)

function getIntersectionNode(headA, headB){if(!headA || !headB) return null;let pA = headA, pB = headB;while(pA != pB){pA = pA ? pA.next : headB;pB = pB ? pB.next : headA;}return pA;        // 可能是交点,也可能是null
}

5. 长度差法(经典写法)

遍历两个单链表 获取其长度。长的链表 先遍历 差值的部分(多出来的那部分长度),遍历到 使两个链表后续的长度相同;两指针 再一起遍历(指针.next),边判断两个节点是否相等,相等则为第一个相交的节点。时间复杂度O(m+n),空间复杂度O(1)。

function getIntersectionNodeByLength(headA, headB){let lenA = 0, lenB = 0;let pA = headA, pB = headB;while(pA) { lenA++; pA = pA.next; }while(pB) { lenB++; pB = pB.next; }pA = headA;pB = headB;if(lenA > lenB){for(let i = 0;i < lenA - lenB; i++) pA = pA.next;}else{for(let i = 0;i < lenB - lenA; i++) pB = pB.next;}while(pA && pB && pA !== pB){pA = pA.next;pB = pB.next;}return pA;
}

参考:判断两个单链表是否相交及找到第一个交点_判断两个链表是否相交并找出交点-CSDN博客

图解LeetCode——160. 相交链表一、题目 给你两个单链表的头节点 headA 和 headB ,请你找出并返回 - 掘金

http://www.dtcms.com/a/520980.html

相关文章:

  • 比较好的建站公司大恒建设集团有限公司网站
  • 一键lnmp搭建wordpress优化设计数学
  • Crew连接多个 MCP 服务器
  • 做母婴育儿类网站好做seo排名吗网站建设细节差异化
  • 中山互联网推广:AI时代的数字营销新逻辑
  • 博罗网站建设费用无锡设计网站找哪家
  • 个人做网站要备案吗公司发展规划怎么写
  • Navicat 完整清理脚本
  • Python及Ipython解释器
  • 昇腾NPU运行Llama模型全攻略:环境搭建、性能测试、问题解决一网打尽
  • 前端通用布局(左侧侧边栏+顶部导航栏+主内容区)
  • 在线做印章的网站如何做网站导航
  • 制作微信商城网站开发怎么做仿制网站
  • 鸿蒙openharmony操作系统LiteOS-A内核技术全解析:架构、性能与开发实践
  • 【MATLAB源码-第303期】基于matlab的蒲公英优化算法(DO)机器人栅格路径规划,输出做短路径图和适应度曲线.
  • KP2203LGA/KP2205LGA芯片功能描述,内置65k/100kHz开关频率振荡器
  • asp网站程序优点东莞黄江网站建设
  • 阿里巴巴网站威海哪里做?苏州高端模板建站
  • 网站开发步骤说明书温州市建筑业联合会
  • wdt接口优化
  • 东莞网站建设服务协议wordpress字段添加按钮
  • 网站建设的技术标准中小企业网站建设渠道
  • 创建网站需要什么技术个人网站建设的方案
  • 为什么做营销型网站邯郸渊博网络有限公司
  • dir()与help()
  • chromium项目中添加源文件(BUILD.gn项目中添加源文件)
  • 网站建设远程工作太原网站建设联系方式
  • 宁波模板建站源码展示网站报价
  • 台式机电脑i9-9900K+Z390-PRO-A更换主板的辛路历程
  • 关于使用「音流」连接「Navidrome」的异地播放问题解决方案