力扣 - 剑指 Offer 52. 两个链表的第一个公共节点
题目
思路1(栈)
- 若两个链表相遇,则从它开始相遇的地方到链表末尾应该都是相同的,那么我们可以将两个链表分别放入两个栈中,然后依次循环比较两个栈顶的节点,同时用
pre记录上一个节点,直到当前两个栈顶节点不相等,那么pre节点就是他们开始相遇的地方
代码
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
LinkedList<ListNode> stack1 = new LinkedList<>();
LinkedList<ListNode> stack2 = new LinkedList<>();
// 使用两个栈分别存储两个链表的元素
while (headA != null) {
stack1.push(headA);
headA = headA.next;
}
while (headB != null) {
stack2.push(headB);
headB = headB.next;
}
// 若两个链表存在相同的节点,则两个栈pop出来的节点应该是一样的
// 如果pop出来的不一样,说明上一个pop出来相同节点才是相遇开始的节点
// 因此我们需要pre来记录上一个相同的节点,初始值要为null,如果没有相遇,那么会直接返回null
ListNode pre = null;
while (!stack1.isEmpty() && !stack2.isEmpty()) {
ListNode p1 = stack1.pop();
ListNode p2 = stack2.pop();
if (p1 != p2) {
break;
}
// 如果没有相遇,就不会执行这条语句,因此此时pre为 null,返回的值也是 null
pre = p1;
}
// 返回结果
return pre;
}
}
复杂度分析
- 时间复杂度:\(O(N+M)\)
- 空间复杂度:\(O(N+M)\)
思路2(差值法)
- 先分别计算两个链表的长度记为
lengthA和lengthB,得到他们的差值n,让长的那个链表先走n步,然后两个链表再一起走,第一个相等的地方,则是链表开始相遇的地方
代码
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
int lengthA = 0;
int lengthB = 0;
ListNode pA = headA;
ListNode pB = headB;
// 先获取两个链表的长度
while (pA != null) {
pA = pA.next;
lengthA++;
}
while (pB != null) {
pB = pB.next;
lengthB++;
}
// 计算链表长度差n,将长的链表先走n步
int n = lengthA > lengthB ? lengthA - lengthB : lengthB - lengthA;
while (lengthA > lengthB && n > 0) {
headA = headA.next;
n--;
}
while (lengthB > lengthA && n > 0) {
headB = headB.next;
n--;
}
// 然后两个链表才开始同时一起走
// 知道两个节点相等 或者 都为null的时候结束循环
while (headA != headB) {
headA = headA.next;
headB = headB.next;
}
return headA;
}
}
复杂度分析
- 时间复杂度:\(O(N+M)\)
- 空间复杂度:\(O(1)\)
思路3(双指针)
- 使用两个指针
pA和pB分别指向两个链表,然后同时前进,如果到了链表末尾,就跳到另一条链表的头节点(要保证不会再跳回来,否则导致死循环) - 在这过程中,要判断节点是否相等,第一次相等的地方就是相交的地方,如果没有那就返回
null - 在
while中的判断条件要为当前两个节点是否相等,因为不这样的话,如果不存在相交的节点,那么循环就会一直重复下去;如果判断条件为当前两个节点是否相等的话,如果没有相交节点也不会一直循环下去,因为两个指针遍历的长度都为两个链表长度之和,所以最后都会指向null,此时都为null相等,跳出循环
代码
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode pA = headA;
ListNode pB = headB;
// 判断是否相等,遇到相同节点,结束循环;如果链表中没有相同节点,那么跳出循环的条件是他们都为 null 的时候
while (pA != pB) {
// 判断的要为当前节点
// 如果判断的是next节点,那么到时候就会导致pA、pB永远不会是null
if (pA == null) {
pA = headB;
} else {
pA = pA.next;
}
if (pB == null) {
pB = headA;
} else {
pB = pB.next;
}
}
return pA;
}
}
复杂度分析
- 时间复杂度:\(O(N)\)
- 空间复杂度:\(O(1)\)
思路4(哈希表)
- 先选择其中一个链表,将其节点全部加入到哈希表中,然后再开始遍历另一个链表,同时也加入到哈希表中
- 如果加入的节点和哈希表冲突了,那么这个节点就是交点
代码
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
HashSet<ListNode> set = new HashSet<>();
// 遍历一次,将链表A里的所有节点添加到set中
while (headA != null) {
set.add(headA);
headA = headA.next;
}
// 再遍历一次链表B,同时将链表的节点添加到set中,如果添加失败返回false,那么说明找到相同的那个节点了,直接返回该节点
while (headB != null) {
if (!set.add(headB)) {
return headB;
}
headB = headB.next;
}
// 如果遍历链表B的时候都没有找到,说明不存在相同的节点,就返回 null
return null;
}
}
复杂度分析
- 时间复杂度:\(O(N+M)\)
- 空间复杂度:\(O(N)\),哈希表所占空间大小
力扣 - 剑指 Offer 52. 两个链表的第一个公共节点的更多相关文章
- 剑指 Offer 52. 两个链表的第一个公共节点 + 链表 + 第一个公共结点 + 双指针
剑指 Offer 52. 两个链表的第一个公共节点 Offer_52 题目详情 题解分析 可以使用两个指针 node1,node2 分别指向两个链表 headA,headB 的头结点,然后同时分别逐结 ...
- 每日一题 - 剑指 Offer 52. 两个链表的第一个公共节点
题目信息 时间: 2019-07-03 题目链接:Leetcode tag: 单链表 难易程度:简单 题目描述: 输入两个链表,找出它们的第一个公共节点. 示例: A: a1 -> a2 \ - ...
- 剑指 Offer 52. 两个链表的第一个公共节点
题目链接 题目描述: 我的题解: 方法一:双指针法 思路分析: 声明两个指针p1,p2 分别指向链表A.链表B. 然后分别同时逐结点遍历 当 p1 到达链表 headA 的末尾时,重新定位到链表 he ...
- [LeetCode]剑指 Offer 52. 两个链表的第一个公共节点
题解 nodeA走一个链表A(A独有+公共),再走B独有的长度, nodeB走一个链表B(B独有+公共),再走A独有的长度. 结果:两者相遇点即为交点:若没有交点,两者都走到null,会返回null. ...
- 【Java】 剑指offer(52) 两个链表的第一个公共结点
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 输入两个链表,找出它们的第一个公共结点. 思路 蛮力法:遍历第一个 ...
- 剑指offer——55两个链表的第一个公共节点
题目描述 输入两个链表,找出它们的第一个公共结点. 题解: 分别遍历两个链表到链尾,并计算其长度,若最后一个节点相同,则存在公共节点 然后让长链表指针从头先移动长度差个节点,然后两个链表指针一起移动, ...
- 【剑指offer】两个链表的第一个公共结点,C++实现
原创文章,转载请注明出处! 博客文章索引地址 # 题目 #举例 如果两个单向链表有公共的节点,那么这两个链表从第一个公共结点开始,之后所有结点都是重合的,不可能再出现分叉.拓扑结构如下图所示: # 思 ...
- Go语言实现:【剑指offer】两个链表的第一个公共结点
该题目来源于牛客网<剑指offer>专题. 输入两个链表,找出它们的第一个公共结点. Go语言实现: //长度长的先走个长度差,然后ab一起比较后面结点 //长度一样,公共结点可能在首结点 ...
- 【剑指offer】两个链表的第一个公共结点
一.题目: 输入两个链表,找出它们的第一个公共结点. 二.思路: 思路一:模拟数组,进行两次遍历,时间复杂度O(n2) 思路二:假定 List1长度: a+n List2 长度:b+n, 且 a&l ...
随机推荐
- mysql学习教程之mysql管理
MySQL 管理 启动及关闭 MySQL 服务器 Windows 系统下 在 Windows 系统下,打开命令窗口(cmd),进入 MySQL 安装目录的 bin 目录. 启动: cd c:/mysq ...
- 实现一个简单的侧边导航Winform程序框架
目录 简介 实现导航面板 实现方法 使用方法 实现标题栏 窗体拖拽及最大化 自定义窗体按钮 标题显示 按钮设置 实现状态栏 整体使用 参考文章 简介 每次新项目都要想着界面怎么设计好,但想来想去上位机 ...
- Cartography Tools(制图工具)
制图工具 1.制图优化 # Process: 分散标记 arcpy.DisperseMarkers_cartography("", "", "EXPA ...
- CAD网页Web端显示开发为什么要以WebGIS的思路来开发?
背景 在之前的博文CAD图DWG解析WebGIS可视化技术分析总结中讲解了如何把CAD的DWG格式的图纸Web可视化的方案.博文发布后,受到不少同行们的关注,也有不少咨询一些专业问题,其中大家可能疑惑 ...
- Mybatis初始化机制
对于任何框架而言,在使用前都要进行一系列的初始化,MyBatis也不例外.本章将通过以下几点详细介绍MyBatis的初始化过程. 1.MyBatis的初始化做了什么 2. MyBatis基于XML配置 ...
- 个人记录:对于python学习的反思和总结(一)
在写代码时,总是遇到写着写着不知道怎么写了的情况,或者无法把自己的想法用程序表达出来,所以有时候我们需要建立一个自己的编程思路,对一个具体程序的编程有一个比较清晰的想法:因此我把自己的思路总结了一下, ...
- Pytorch——张量 Tensors
张量 Tensors 1.torch.is_tensor torch.is_tensor(obj) 用法:判断是否为张量,如果是 pytorch 张量,则返回 True. 参数:obj (Object ...
- 第四次Alpha Scrum Meeting
本次会议为Alpha阶段第四次Scrum Meeting会议 会议概要 会议时间:2021年4月28日 会议地点:线上会议 会议时长:18min 会议内容简介:本次会议主要由每个人展示自己目前完成的工 ...
- Beta_Scrum Meeting_2
会议概要 日期:2021年5月30日 出席人员:除zwh以外的所有人员 会议概述:讨论前两天工作进度以及后两天工作计划 人员分工 组员 负责 前两日完成的工作 后两日即将完成的工作 遇到的困难 hcc ...
- C语言零基础入门难发愁,那就快来看看这篇基础整理资料吧
C语言程序的结构认识 用一个简单的c程序例子,介绍c语言的基本构成.格式.以及良好的书写风格,使小伙伴对c语言有个初步认识. 例1:计算两个整数之和的c程序: #include main() { in ...